Writing a function to catch http errors while using fetch to get data from api-endpoint [closed]

// 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 handleErrorsto this

function handleErrors(res) {
    if (!!res.ok) throw new Error(res.error);
    return res;
}

Then it works as expected

My question(s) are

  1. What is wrong with my implementation of the function handleErrors
  2. What does !! operator do?
  3. Good sources to learn asynchronous programming and more specifically ajax

Answer

  1. Handel error input argument is an array not the res you receive in the first then as you are returning res.json().

  2. Because 1. inside the error handler res.ok is undefined, hence !!undefined is false.

  3. GIYF

Hope that helps. 😉

Side notes:

  1. If fetch fails, it would go straight to the catch function so there is no need to check res.ok.
  2. 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();