Handling response status using fetch in react JS

According to MDN documentation:

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

A fetch() promise will reject with a TypeError when a network error is encountered or CORS is misconfigured on the server side, although this usually means permission issues or similar — a 404 does not constitute a network error, for example. An accurate check for a successful fetch() would include checking that the promise resolved, then checking that the Response.ok property has a value of true. The code would look something like this:

fetch('flowers.jpg').then(function(response) {
   if(response.ok) {
     return response.blob();
 }
 throw new Error('Network response was not ok.');
}).then(function(myBlob) { 
   var objectURL = URL.createObjectURL(myBlob); 
   myImage.src = objectURL; 
}).catch(function(error) {
 console.log('There has been a problem with your fetch operation: ', 
 error.message);
});

Looking at your code, I don't think your 408 error check will ever run. I don't think it did in fact. Basically what the code above is doing is returning the json response if the request is 200ish ok, otherwise it's throwing an error. If an error occurs, your second then never runs and it gets thrown to your catch block. Perhaps you can set the isLoading: false there?

Also you're log statement for end of api isn't correct. That's being called before your promise completes.


If you want to know both the json response and error code in the same return value, I recommend this method:

async function loginUser(credentials) {
  var resp;
  return fetch("http://127.0.0.1:8000/api/token-auth/", {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify(credentials)
  }).then(response => {
    resp = response;
    return response.json();
  }).then(json => {
    return {
      response: resp,
      json: json,
      error: !resp.ok
    };
  });
}

In this case you will get an array with response, json and error field. This is a better aproach if you use API with per field error messages like this:

{"username":["This field is required."],"password":["This field is required."]}

Throw an error when the response is not OK so that it proceeds directly to the catch:

fetch(api)
  .then((response) => {
    if(!response.ok) throw new Error(response.status);
    else return response.json();
  })
  .then((data) => {
    this.setState({ isLoading: false, downlines: data.response });
    console.log("DATA STORED");
  })
  .catch((error) => {
    console.log('error: ' + error);
    this.setState({ requestFailed: true });
  });