"Failed to execute 'fetch' on 'Window': Illegal invocation" error when working with schoology API

44 Views Asked by At

I'm building a planner app and trying to integrate it with schoology's API. I'm using this GitHub repository https://github.com/hieyou1/schoology-api and I'm getting an unexpected error when I'm calling to request a token.

Here is what this section of my code essentially looks like:

import { SchoologyAPI } from 'schoology-api';//https://github.com/hieyou1/schoology-api
const client_key = "1234";
const secret = "000";
const client = new SchoologyAPI(client_key, secret, "https://schoology.[SchoolName].org/");

async function getClient () {
     client.getRequestToken()
}
export default function CreateHeader(){
getClient();
}

It says its an illegal invocation and it seems to be a problem with the repository in the index.ts file on line 112 which is the function getRequestToken().

  async getRequestToken(): Promise<Token> {
        const Authorization = this.getUnsignedAuthHeader();
        let res = await (await this.fetch(this.api_base + '/oauth/request_token', {
            headers: { Authorization }
        })).text();
        const token = qsParse(res);
        this.setToken(token);
        return token;
    }

I've tried changing the client.getRequestToken() to client.getRequestToken.call(), but then it says it can't read the getUnsignedAuthHeader() function in the repository

I've attempted to use solutions in the Fetch TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation question, but none of them seemed to work.

Here is the complete code from the repository that I'm using

import { v4 } from "uuid";
import { isBrowser as IS_BROWSER } from "is-in-browser";
const qsParse = (search: string): any => {
    return Object.fromEntries(new URLSearchParams(search).entries());
};
const DEFAULT_SITE_BASE = 'https://www.schoology.com';
const SCHOOLOGY_API_HOST = 'https://api.schoology.com';
const SCHOOLOGYTEST_API_HOST = 'https://api.schoologytest.com';
const REALM_PARAM = { 'OAuth realm': 'Schoology API' };

type SigMethod = 'HMAC-SHA1' | 'PLAINTEXT';

type FullToken = {
    oauth_consumer_key: string,
    oauth_nonce: string,
    oauth_signature_method: SigMethod,
    oauth_timestamp: number,
    oauth_token: string,
    oauth_version: '1.0',
};

type Token = {
    oauth_token: string;
    oauth_token_secret: string;
};

const headerFormat = (components: Record<string, string | number>) => {
    const parts: string[] = []
    Object.keys(components).forEach(key => parts.push(key + '="' + components[key] + '"'))
    return parts.join(',')
};

const baseStringFormat = (components: Record<string, string | number>) => {
    const parts: string[] = []
    Object.keys(components).forEach(key => parts.push(key + '=' + components[key]))
    return parts.join('&')
};

export class SchoologyAPI {
    client_key: string
    client_secret: string
    site_base: string
    api_base: string
    oauth_token: string
    oauth_token_secret: string
    redirectLoop: boolean;
    fetch: (url: any, init: any) => any;

    constructor(client_key: string, client_secret: string, site_base = DEFAULT_SITE_BASE, api_host: string = null) {
        if (IS_BROWSER) {
            this.fetch = window.fetch.bind(window)
        } else {
            this.fetch = require("node-fetch");
        }
        this.client_key = client_key;
        this.client_secret = client_secret;
        this.site_base = site_base;
        this.api_base = `${(api_host ?? ((site_base.indexOf('schoologytest') !== -1) ? SCHOOLOGYTEST_API_HOST : SCHOOLOGY_API_HOST))}/v1`;
        this.redirectLoop = IS_BROWSER;
    }

    getAuthHeaderComponents(signatureMethod: SigMethod = 'PLAINTEXT', token = ''): FullToken {
        const nonce = v4();
        const timestamp = Math.round(Date.now() / 1000);
        return {
            oauth_consumer_key: this.client_key,
            oauth_nonce: nonce,
            oauth_signature_method: signatureMethod,
            oauth_timestamp: timestamp,
            oauth_token: token,
            oauth_version: '1.0',
        };
    }

    getUnsignedAuthHeader(): string {
        return headerFormat({
            ...REALM_PARAM,
            ...this.getAuthHeaderComponents(),
            oauth_signature: this.client_secret + '%26'
        });
    }

  

   
    setToken(token: Token) {
        this.oauth_token = token.oauth_token;
        this.oauth_token_secret = token.oauth_token_secret;
    }

    async getRequestToken(): Promise<Token> {
        const Authorization = this.getUnsignedAuthHeader();
        let res = await (await this.fetch(this.api_base + '/oauth/request_token', {
            headers: { Authorization }
        })).text();
        const token = qsParse(res);
        this.setToken(token);
        return token;
    }
 

One thing I just noticed, no matter how I shift the code, the error always occurs at line 112

0

There are 0 best solutions below