I am using fetch api for fetching an URL that might return:
Response : status = 200, json body = {'user': 'abc', 'id': 1}
or
Response : status = 400 , json body = {'reason': 'some reason'}
or
Response : status = 400 , json body = {'reason': 'some other reason'}
I want to make a separate function request() that I use from various parts of my code as follows:
request('http://api.example.com/').then( // status 200 comes here data => // do something with data.id, data.user ).catch( // status 400, 500 comes here error => // here error.reason will give me further info, i also want to know whether status was 400 or 500 etc ) I am unable to do the split between 200 and 400,500 (i have tried by throwing an error). When I throw an error, I am finding it hard to still extract the JSON body (to use for error.reason).
My current code is as follows:
import 'whatwg-fetch'; /** * Requests a URL, returning a promise */ export default function request(url, options={}) { console.log('sending api request, url = ' + url) return fetch(url, options) .then(checkStatus) .then(parseJSON) .then((data) => ({data})) .catch((err) => ({err})); } function checkStatus(response) { if (response.status >= 200 && response.status < 300) { return response; } const error = new Error(response.statusText); error.response = response; throw error; } function parseJSON(response) { return response.json(); // json() is a promise itself } I have tried to solve this by doing as follows, by inverting the order of .then() calls, but does not work
export default function request(url, options) { return fetch(url, options) .then(parseJSON) // note that now first calling parseJSON to get not just JSON but also status. .then(checkStatus) // i.e. Inverted order of the two functions from before .then((data) => ({data})) .catch((err) => ({err})); } function checkStatus({data, status}) { if (status >= 200 && status < 300) { return data; } else { // const error = new Error(response.statusText); const error = new Error("Something went wrong"); // error.response = response; error.data = data; throw error; } } function parseJSON(response) { let jsonBody response.json().then(json => { jsonBody = json // this does not help, i thought it will make jsonBody fill up, but seems its in a diff thread }) return { data: jsonBody, status: response.status // my aim is to send a whole dict with status and data to send it to checkStatus, but this does not work } }
request('http://api.example.com/').then( function(data){ //success call back, i.e 200 }, function( jqXHR, textStatus, errorThrown) { // error call back. Check the status code here } );this does not help- the issue with that code is that Promises don't make asynchronous code synchronous (the code assumes they do)