Handling response status using fetch in react JS Handling response status using fetch in react JS reactjs reactjs

Handling response status using fetch in react JS


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 });  });


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 capture both the response's status code and the response's body, you can use this pattern. For my projects, I've created a static class called Endpoint to handle my API calls.

export class Endpoint {    static lastStatus = '';    static Get = (url, OKCallback, errorCallback = null) => {        fetch(url)            .then(response => {                Endpoint.lastStatus = response.status;                return response.json();            })            .then(getResponse => {                if (Endpoint.lastStatus == 200) {                    OKCallback(getResponse.body);                //} else if (Endpoint.lastStatus == 408) {                //    Special logic or callback for status code 408 goes here.                } else {                    console.log("API Error: " + JSON.stringify(getResponse));                    if (errorCallback != null) {                        errorCallback(getResponse);                    }                }            });    }}

If you have specific HTTP Status Codes that you want handled separately, like 408, you can add your own logic or callbacks to handle them in the second "then" block.


P.S. This way works for the cases I've tested, but I'm not sure it's the best approach. Constructive feedback is invited.