fetch() unexpected end of input

Viewed 147913

I am using fetch() to grab data from api server. My error looks like this:

Uncaught (in promise) SyntaxError: Unexpected end of input at 
  fetch.then.blob.

Can you please tell me what am I doing wrong.

const weatherAPi ='https://www.metaweather.com/api/location/523920';
fetch(weatherAPi, {
  mode: 'no-cors'
}).then(blob => blob.json())
  .then(data => console.log(data))
9 Answers

I had the same problem. in my case it wasn't caused by the response type of 'opaque' as the solution pointed. This code cause an error with empty response, because 'fetch' doesn't accept responses with empty body :

return fetch(urlToUser, parameters)
.then(response => {
  return response.json()
})
.then((data) => {
  resolve(data)
})
.catch((error) => {
  reject(error)
})

Instead, in my case this works better :

return fetch(urlToUser, parameters)
.then(response => {
  return response.text()
})
.then((data) => {
  resolve(data ? JSON.parse(data) : {})
})
.catch((error) => {
  reject(error)
})

Gettting the text doesn't give the error even with the empty body. Then check if data exists and resolve. I hope it helps :-)

Lots of good responses but I chose this:

      const response = await fetch(url, {
        method: 'GET',
        headers: {
          Authorization: 'Bearer ' + accessToken
        }
      });
      const string = await response.text();
      const json = string === "" ? {} : JSON.parse(string);
      return json;

(for people coming later but dealing with this problem "Unexpected end of JSON input")

The problem in many times is server error or just invalid URL but you can't see it because all examples on internet how to work with fetch are missing one important part - the server or network failure.

The correct way how to deal with fetch is to test response if contains errors before conversion to json.

Check the part of the first then in example where resp.ok is tested:

async function fetchData() {
    return await fetch('https://your-server.com/some-NOt-existing-url/')
        .then(resp => {
            if (!resp.ok) {
                throw `Server error: [${resp.status}] [${resp.statusText}] [${resp.url}]`;
            }
            return resp.json();
        })
        .then(receivedJson => {
            // your code with json here...
        })
        .catch(err => {
            console.debug("Error in fetch", err);
            setErrors(err)
        });
}

Adding to Pibo's answer...

I dont know how this happened, but I solved it just by changing

return fetch(url, {
        mode: "no-cors" // <----------------
    })
    .then((res)=>{
        return res.text();
    })
    .then((data)=>{
        console.log(data);
        return new Promise((resolve, reject)=>{
            resolve(data ? JSON.parse(data) : {})
        })
    })

to

return fetch(url, {
        mode: "cors" // <----------------
    })
    .then((res)=>{
        return res.text();
    })
    .then((data)=>{
        console.log(data);
        return new Promise((resolve, reject)=>{
            resolve(data ? JSON.parse(data) : {})
        })
    })

unexpected end of input

 // .then((response) => response.json()) .  // commit out this part

https://github.com/github/fetch/issues/268

fetch(url, {
    method: 'POST',
    body: JSON.stringify(requestPayload),           
    headers: {
        'Content-type': 'application/json; charset=UTF-8',
        Authorization: 'Bearer ' + token,
    },
})
    // .then((response) => response.json()) .  // commit out this part
    .then((json) => {
        console.log("response :- ", json);
        getCheckedInTrailersList();
    }).catch((error)=>{
        console.log("Api call error ", error.message);
        alert(error.message);
});

@KevBot save me. I meet the problem accidentally. The request method works all along but it failed suddenly. Now I know it is because I add the 'no-cors' option to fetch method. I request multiple api. Some need the option some don't. So I modified my code like the following:

// determine whether add mode option to fetch method
const option =is_outer? {
  mode: 'no-cors'
} : {};
ret = fetch(url, option).then(data => {
    if (url.endsWith('txt')) {
      return data.text()
     } else {
      const j = data.json();
     ...
Related