chriskirknielsen
chriskirknielsen

Reputation: 2929

Converting a fetch-based function to async that previously returned a promise

I have a super_fetch function that "extends" fetch() by performing a user session check before running fetch:

function super_fetch() {
    checkUserSessionIsStillValid(); // Check if the user can interact

    return fetch(...arguments); // Create the fetch call
}

checkUserSessionIsStillValid() makes a fetch of its own and .then() processes the result and displays an error on the UI if the session is invalid. Technically it is not stopping the super_fetch from executing its fetch call, though.

I updated the checkUserSessionIsStillValid function to return a promise which will resolve to true or false. I reworked my function to take advantage of this:

async function super_fetch() {
    let isSessionValid = await checkUserSessionIsStillValid(); // Check if the user can interact

    if (!isSessionValid) { return false; } // Invalid session, don't pull data

    return fetch(...arguments); // Create the fetch call
}

Now my issue is that by doing this, I change the nature of the returned value of super_fetch from a Promise containing a Response, to… something else, meaning that things like super_fetch(url, args).then((response) => response.json()) throw errors.

I am uncertain of what exactly that "something else" is, and how I can solve for it at the function definition level, since I cannot go in and edit every single super_fetch call in my code base.

My understanding of async/await is still limited but if you know what is causing this and how I can resolve it (either by example or by specific documentation links), I'd very much appreciate it.

Thanks!

Upvotes: 0

Views: 78

Answers (2)

jcubic
jcubic

Reputation: 66490

I would use throw instead of return false; that way super_fetch(...).then will not be called, you can make it throw real error so catch will work like the one on fetch.

async function super_fetch() {
    let isSessionValid = await checkUserSessionIsStillValid();

    if (!isSessionValid) {
       throw new Error('Invalid session');
    }

    return fetch(...arguments);
}

the other solution if you need then and json()

async function super_fetch() {
    let isSessionValid = await checkUserSessionIsStillValid();

    if (!isSessionValid) {
       return {
           json: () => ({error: 'Invalid Session'})
       };
    }

    return fetch(...arguments);
}

and as reference:

function super_fetch() {
   return fetch(...arguments);
}

async function super_fetch() {
   return fetch(...arguments);
}

both are exactly the same. If async function return promise it will be the result, the only difference is that if you return value it will be wrapped in promise (and you can use await to stop the function) so:

async function super_fetch() {
    let isSessionValid = await checkUserSessionIsStillValid();

    if (!isSessionValid) {
       return false;
    }

    return fetch(...arguments);
}

is the same as:

function super_fetch() {
    var args = arguments;
    checkUserSessionIsStillValid().then((isSessionValid) => {
        if (!isSessionValid) {
            return false;
        }
        return fetch(...args);
    });
}

or simpler example:

function super_fetch() {
    if (!isSessionValid) {
        return Promise.resolve(false);
    }
    return fetch(...arguments);
}

Upvotes: 2

zfrisch
zfrisch

Reputation: 8660

Answer:

All async functions are synonymous with Promises. You can use Promise.reject() within the async function to skip the .then and go to .catch

async function super_fetch() {
    let isSessionValid = await checkUserSessionIsStillValid(); // Check if the user can interact

    if (!isSessionValid) { return Promise.reject("Session is Not Valid"); } // Invalid session, don't pull data

    return fetch(...arguments); // Create the fetch call
}

super_fetch(url, args).then((response) => response.json()).catch(console.error)

Example:

async function demo() {
  return Promise.reject("whatever");
}

demo().then(console.log).catch(console.error);

Upvotes: 1

Related Questions