fetch response.json() and response.status
I was faced with the exact same problem last week. The .json
method returns a promise to the parsed JSON, not the parsed JSON itself. If you want to access both the response and the parsed JSON at once, you'll need to use nested closures like this:
fetch(url)
.then(response => {
response.json().then(parsedJson => {
// code that can access both here
})
});
Alternatively, you can use the async/await
syntax:
async function fetchTheThing() {
const response = await fetch(url);
const parsedJson = await response.json();
// code that can access both here
}
Of course, you'll want to check for errors, either with a .catch(...)
call on a Promise or with a try...catch
block with an async
function. You could make a function that handles JSON and error cases, and then reuse it for all fetches. For example, something like this:
function fetchHandler(response) {
if (response.ok) {
return response.json().then(json => {
// the status was ok and there is a json body
return Promise.resolve({json: json, response: response});
}).catch(err => {
// the status was ok but there is no json body
return Promise.resolve({response: response});
});
} else {
return response.json().catch(err => {
// the status was not ok and there is no json body
throw new Error(response.statusText);
}).then(json => {
// the status was not ok but there is a json body
throw new Error(json.error.message); // example error message returned by a REST API
});
}
}
I don't think it's the best design pattern, but hopefully this clarifies how the fetch API works.
Your status is not visible in the second then
. You can just get the two properties in the single then
.
json()
returns a new Promise to you, so you need to create your object inside the then
of the result of that function. If you return a Promise from a function, it will be fulfilled and will return the result of the fulfillment - in our case the object.
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then(r => r.json().then(data => ({status: r.status, body: data})))
.then(obj => console.log(obj));