Reputation: 657
I have a wrapper function for the fetch api to fetch different endpoints to my api but somehow it keeps complaining that there is unhandled rejection TypeError: Cannot read property 'catch' of undefined
const apiRequest = (url) => {
return fetch()
.then(async resp =>{
const json = await resp.json()
if(json.status == "success") return json
return Promise.reject('err')
})
.catch(err => {
return Promise.reject(err)
})
}
calling the function like:
apiRequest('/test')
.then(data => console.log(data))
.catch(err => console.log(err))
what am I doing wrong?
Upvotes: 2
Views: 5172
Reputation: 1075317
Note: When this answer was posted, the question didn't have the return
. The OP added it afterward, claiming it was in their original code. But they also accepted the answer, so something below must have helped... :-)
apiRequest
needs to return the promise chain. Right now, it doesn't, so calling it returns undefined.
const apiRequest = (url) => {
return fetch(url) // *** Note: Added `url` here
// ^−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
.then(async resp =>{
const json = await resp.json()
if(json.status == "success") return json
return Promise.reject('err')
})
.catch(err => {
return Promise.reject(err)
})
}
But, three things:
There's no point whatsoever to that catch
handler; and
You need to check for response success before calling json
; and
There's no reason for that then
handler to be an async
function.
Instead:
const apiRequest = (url) => {
return fetch(url) // *** Note: Added `url` here
.then(resp => {
if (!resp.ok) {
throw new Error("HTTP status " + resp.status);
}
return resp.json();
})
};
(I've also added some missing semicolons there, but if you prefer to rely on ASI, just leave them off.)
If the fetch
promise is rejected, that rejection will be carried through to the promise from apiRequest
for the caller to handle. If the fetch
promise is fulfilled but resp.ok
is false
(because there was an HTTP level error like a 404 or 500), the promise from apiRequest
will be rejected with the error thrown in the then
handler. If those things work but the json
call fails, the promise from apiRequest
will be rejected with the error from json
. Otherwise, the promise from apiRequest
will be fulfilled with the parsed data.
It can also be a concise form arrow function if you prefer:
const apiRequest = (url) => fetch(url).then(resp => { // *** Note: Added `url` to `fetch` call
if (!resp.ok) {
throw new Error("HTTP status " + resp.status);
}
return resp.json();
});
Your original code used an async
function in then
. If you can ues async
functions in your environment, you may prefer to make apiRequest
an async
function:
const apiRequest = async (url) => {
const resp = await fetch(url); // *** Note: Added `url` here
if (!resp.ok) {
throw new Error("HTTP status " + resp.status);
}
return resp.json();
};
Upvotes: 5