Valeriy Donika
Valeriy Donika

Reputation: 466

Fetch TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation

I trying to use fetch for calls to backend from react without libs like Axios.

api.ts

export const sendSuggestion = ((data: any): Promise<any> => {
console.log(JSON.stringify(data));
const apiUrl = `/api/suggest/`;
return fetch(apiUrl, {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify(data)
}).then(checkStatus)
    .then(r => r.json())
    .then(data => {
        console.log(data);
    });
});

const checkStatus = ((response: any) => {
  if (response.ok) {
    return response;
  } else {
    var error = new Error(response.statusText);
    console.log(error);
  //return Promise.reject(error);
  }
})

Also i include npm module which is polyfill https://www.npmjs.com/package/unfetch and import it in my code

 import fetch from 'unfetch'


 console.log(fetch) returns in console:
 function fetch() { [native code] } 

I can`t understand what the problem.

Upvotes: 19

Views: 32517

Answers (4)

Qback
Qback

Reputation: 4908

In my case I had a class like this:

export class HTTPClient {
  constructor(fetch: FetchFunction = window.fetch) {
    this.fetch = fetch;
  }
  
  async performRequest(data: any) {
    return await this.fetch(data);
  }
};

and performRequest throws this error (Fetch TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation).

I've changed it to:

export class HTTPClient {
  constructor(
    fetch: FetchFunction = (...args) => window.fetch(...args)
  ) {
    this.fetch = fetch;
  }

  async performRequest(data: any) {
    return await this.fetch(data);
  }
};

and it works now.

I guess the problem is that in the first example this param was rebound to HTTPClient therefore fetch function had no this referencing window as it needed.

Upvotes: 14

Lesley Livingstone
Lesley Livingstone

Reputation: 3

Using Axios instead of Fetch solved the problem for me.

Upvotes: -4

Brad Johnson
Brad Johnson

Reputation: 1924

Very specific use-case, but I encountered this while building a Chrome Extension.

The problem was that I specified headers in the request options as a list of objects, when it should be an object.

I was building the following request:

const requestOptions = {
  method: 'POST',
  searchParams: {
    code: code,
  },
  headers: [
    {'content-type': 'application/x-www-form-urlencoded'},
  ],
};
const getAccessToken = `https://example.com/oauth2/token`;
fetch(getAccessToken, requestOptions)
  .then(r => r.text())
  .then(token => {
    console.log('token is', token);
  });

I fixed it by changing:

headers: [
  {'content-type': 'application/x-www-form-urlencoded'},
],

to:

headers: {
  'content-type': 'application/x-www-form-urlencoded',
},

Upvotes: 9

Tiago Gouv&#234;a
Tiago Gouv&#234;a

Reputation: 16740

Using unfetch you can do:

const fetch = unfetch.bind();

If you want to use window:

const fetch = window.fetch.bind(window);

Upvotes: 28

Related Questions