I'm fetching an API that returns a json but when it has an error, it returns only a text (In node with express, results are returned with .json({})
and errors with .send('string')
), but I can't modify the API
So I'm trying to make something that reads the json, but if it's an text, it will go in .catch
where the error is the text.
Here is what I have tried but with no success.
fetch(apiUrl)
.then(res => {
try {
let json = res.json()
return json
} catch (error) {
return new Promise((resolve, reject) => reject(res.text()))
}
})
.then(res => {
// get result from res.json() **res == res.json**
})
.catch(error => {
// get result from res.text() **res == res.text**
})
How can I achieve this? How to get res.json()
in the next .then()
but if it fails, get res.text()
in the .catch
?
I want to get the .text
in .catch
. I don't know why, but throwing res.text()
doesn't work.
To get JSON from the server using the Fetch API, you can use the response. json() method. The response. json() method reads the data returned by the server and returns a promise that resolves with a JSON object.
The jQuery code uses getJSON() method to fetch the data from the file's location using an AJAX HTTP GET request. It takes two arguments. One is the location of the JSON file and the other is the function containing the JSON data. The each() function is used to iterate through all the objects in the array.
The Fetch API allows you to asynchronously request for a resource. Use the fetch() method to return a promise that resolves into a Response object. To get the actual data, you call one of the methods of the Response object e.g., text() or json() . These methods resolve into the actual data.
POST request using fetch API:To do a POST request we need to specify additional parameters with the request such as method, headers, etc. In this example, we'll do a POST request on the same JSONPlaceholder and add a post in the posts. It'll then return the same post content with an ID.
Another approach would be to simply format eveyrthing to text initially and only then try to parse it, while throwing an error in case of parsing issues.
fetch("http://maps.googleapis.com/maps/api/geocode/json?address=google")
.then(res => res.text())
.then(body => {
try {
return JSON.parse(body);
} catch {
throw Error(body);
}
})
.then(console.log)
.catch(console.error);
fetch("http://maps.googleapis.com/maps/api/geocode/xml?address=google")
.then(res => res.text())
.then(body => {
try {
return JSON.parse(body);
} catch {
throw Error(body);
}
})
.then(console.log)
.catch(console.error);
Ideally, your client application should know what response kind to expect and have static code that calls the appropriate method.
Another way to deal with your situation is to inspect the response contentType
and call .json()
or .text()
depending on particular response header value.
handleResponseStatusAndContentType(response) {
const contentType = response.headers.get('content-type')!;
if (response.status === 401) throw new Error('Request was not authorized.');
if (contentType === null) return Promise.resolve(null);
else if (contentType.startsWith('application/json;')) return response.json();
else if (contentType.startsWith('text/plain;')) return response.text();
else throw new Error(`Unsupported response content-type: ${contentType}`);
}
Usage:
return fetch(
url,
requestInit,
)
.then(response => handleResponseStatusAndContentType(response))
.catch(error => {
console.error(error);
return error;
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With