I have a fetch()
call in function myFetch()
(returns the fetch
's return value), and would like to wrap it in another function callApi()
. My goal is to make callApi()
return a Promise, such that:
status_code: body
where status_code
and body
are both from the HTTP response.callApi()
can reconstruct this same message.However, I do not know how to write the callApi()
function. My attempt only ended up with this (where myFetch()
is the call to fetch
):
return new Promise(
(resolve, reject) => {
myFetch()
.then((response) => {
if (response.ok) {
resolve(response);
} else {
reject(`${response.status}: ${response.text}`);
}
}, (error) => {
reject(error);
});
}
);
As you see, response.text
is a Promise, but I need the string there.
How can I achieve my goal?
In addition, if I also need to receive JSON response (from the fetch
), will there be any difference?
You shouldn't create a new promise with new Promise
when you already have a promise -- the one returned by myFetch
.
Secondly, you'll need to call the text
method on the response, and construct the string when that returned promise resolves.
It may be easier to use async
await
syntax:
async function myApi() {
try {
const response = await myFetch();
const body = await response.text();
return response.ok ? body : `${response.status}: ${body}`;
} catch(e) {
return e;
}
}
Here the returned promise will never reject. If you want the promise to reject unless the response status is ok, then leave out the try..catch
wrapper, and do:
async function myApi() {
const response = await myFetch();
const body = await response.text();
if (!response.ok) throw `${response.status}: ${body}`;
return body;
}
When you want to use the json
method instead of text
, then you'd want to produce an object instead of a string, and then it might be a better idea to always return an object that has the same toplevel keys:
The version that will never return a promise that rejects:
async function myApi() {
let ok = false, error = true, status;
try {
const response = await myFetch();
({ ok, status }) = response;
body = await response.json();
error = false;
} catch(e) {
body = e;
}
return { ok, error, status, body };
}
The version that will reject the promise when the response is not ok:
async function myApi() {
let ok = false, error = true, status;
try {
const response = await myFetch();
({ ok, status }) = response;
body = await response.json();
error = false;
} catch(e) {
body = e;
}
if (!ok) throw { error, status, body };
return { error, status, body };
}