Code Snippets
/

Fetch with Async/Await Recipes

Fetch with Async/Await Recipes

The browser and Node 22+ both ship `fetch`, but the easy-to-miss details (`response.ok`, content-type parsing, body shape on POST, parallel error isolation) are exactly where bugs hide. This snippet collects four recipes built on `async`/`await` and a mocked `fetch` so each example runs end-to-end. Use it as the baseline for code that talks to JSON APIs without reaching for axios or a wrapper library.

JavaScript
Medium
4 snippets
js-fetch-api
async-await
promises
js-error-types

705 views

4

// Mock fetch so the example runs end-to-end
globalThis.fetch = async (url) => {
    if (url.endsWith('/users/1')) {
        return new Response(JSON.stringify({ id: 1, name: 'Ada' }), {
            status: 200,
            headers: { 'Content-Type': 'application/json' }
        });
    }
    return new Response('not found', { status: 404 });
};

async function getJSON(url) {
    const response = await fetch(url);
    if (!response.ok) {
        throw new Error(`HTTP ${response.status} on ${url}`);
    }
    return response.json();
}

(async () => {
    try {
        const user = await getJSON('https://api.example.com/users/1');
        console.log('user:', user);
    } catch (err) {
        console.error('failed:', err.message);
    }
    try {
        await getJSON('https://api.example.com/users/999');
    } catch (err) {
        console.error('failed:', err.message);
    }
})();

The two non-obvious moves here are checking response.ok and using await response.json(). fetch only rejects on network failures, so a 404 or 500 still resolves successfully and you must inspect response.status (or the boolean shortcut response.ok, which is true for 200-299). response.json() returns a promise of the parsed body, which is why you need a second await after the first. The outer try/catch catches both transport errors and the manual throw, so callers handle one failure shape regardless of whether the network or the server caused it.