// github users document.getElementById('btn3').addEventListener('click', getExternal); // fetch from external api function getExternal() { fetch('https://api.github.com/users') .then(function (res) { console.log(res.ok); //true return res.json(); }) .then(handleErrors) .then(function (users) { // console.log(data); let output = ''; users.forEach(user => output += `<li>${user.login}</li>`); document.getElementById('output').innerHTML = output; }) .catch(function (err) { console.log(err); }); } // handle fetch http errors function handleErrors(res) { if (!res.ok) throw new Error(res.error); return res; }
Output of above code in developer console
true app.js:55 Error at handleErrors (app.js:61)
Also If I change my function handleErrors
to this
function handleErrors(res) { if (!!res.ok) throw new Error(res.error); return res; }
Then it works as expected
My question(s) are
- What is wrong with my implementation of the function
handleErrors
- What does
!!
operator do?- Good sources to learn asynchronous programming and more specifically ajax
Answer
Handel error input argument is an array not the
res
you receive in the first then as you are returningres.json()
.Because 1. inside the error handler
res.ok
isundefined
, hence!!undefined
is false.GIYF
Hope that helps. 😉
Side notes:
- If fetch fails, it would go straight to the catch function so there is no need to check
res.ok
. - Follow the single responsibility principle. One function should only do one thing. Isn’t it more readable this way?
function getExternal() { return fetch('https://api.github.com/users') .then(function (res) { return res.json(); }); } function modifyDOM (users) { let output = ''; users.forEach(user => output += `<li>${user.login}</li>`); document.getElementById('output').innerHTML = output; } function run() { getExternal() .then((users) => modifyDOM(users)) .catch(function (err) { console.log(err); }); } // or its point free version // function run() { // getExternal() // .then(modifyDOM) // .catch(console.log); // } run();