DEV Community

Cover image for The Easy Way to Cancel Fetch Requests When You Don’t Need Them
Rigal Patel
Rigal Patel

Posted on

The Easy Way to Cancel Fetch Requests When You Don’t Need Them

In this blog, I’ll walk you through the practical steps of cancelling a fetch request using JavaScript, with a focus on the AbortController API. By the end, you’ll have a clear understanding of how to make your web apps more responsive and resource-friendly.

Why Would You Need to Cancel a Fetch Request?

Cancelling fetch requests is crucial in scenarios where:

  • User Experience: When users navigate away from a page, there’s no need to continue fetching data for that page.

  • Search Optimization: In search features where each keystroke triggers a request, it’s more efficient to cancel the previous request before sending a new one.

  • Timeout Scenarios: In case of network delays or long-running requests, you might want to set a timeout and cancel the request if it exceeds a certain duration.

Understanding AbortController

The AbortController API provides an elegant way to cancel fetch requests. It works by creating an AbortController instance, whose signal is passed to the fetch request. If you call the abort() method on the controller, it cancels the request.

Step-by-Step Guide to Cancelling Fetch Requests

1. Basic Setup Using AbortController

Let’s start with the most basic example: creating an AbortController and cancelling a fetch request.

// Step 1: Create an instance of AbortController
const controller = new AbortController();

// Step 2: Pass the signal to the fetch request
fetch('https://jsonplaceholder.typicode.com/posts', { signal: controller.signal })
    .then(response => response.json())
    .then(data => console.log('Data:', data))
    .catch(err => {
        if (err.name === 'AbortError') {
            console.log('Fetch request was canceled');
        } else {
            console.error('Fetch error:', err);
        }
    });

// Step 3: Cancel the fetch request
controller.abort();

Enter fullscreen mode Exit fullscreen mode

2. Practical Use Case: Cancelling Requests on User Interaction
One common scenario is cancelling a fetch request in response to user interaction. For instance, when implementing a search feature, each keystroke might trigger a new fetch request. Cancelling the previous request prevents outdated or irrelevant data from being processed.

let controller;

function search(query) {
    // Cancel the previous request if it exists
    if (controller) {
        controller.abort();
    }

    // Create a new controller for the new request
    controller = new AbortController();

    // Fetch data with the new controller
    fetch(`https://jsonplaceholder.typicode.com/posts?query=${query}`, { signal: controller.signal })
        .then(response => response.json())
        .then(data => console.log('Search results:', data))
        .catch(err => {
            if (err.name === 'AbortError') {
                console.log('Previous request canceled');
            } else {
                console.error('Fetch error:', err);
            }
        });
}

// Example usage: simulate user typing
search('React');
search('Vue'); // The request for 'React' is canceled

Enter fullscreen mode Exit fullscreen mode

3. Implementing Timeout for Fetch Requests
Timeouts are essential when dealing with unreliable network conditions. Using AbortController, you can easily implement a timeout mechanism that cancels the fetch request if it takes too long.

function fetchWithTimeout(url, timeout = 5000) {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), timeout);

    return fetch(url, { signal: controller.signal })
        .then(response => {
            clearTimeout(timeoutId);
            return response.json();
        })
        .catch(err => {
            if (err.name === 'AbortError') {
                console.log('Fetch request timed out');
            } else {
                console.error('Fetch error:', err);
            }
        });
}

// Example usage
fetchWithTimeout('https://jsonplaceholder.typicode.com/posts', 3000)
    .then(data => console.log('Data:', data));

Enter fullscreen mode Exit fullscreen mode

Handling Fetch Request Cancellation Gracefully

When cancelling fetch requests, it’s important to handle them gracefully. This involves distinguishing between errors caused by cancellations and other types of errors.

fetch(url, { signal: controller.signal })
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(err => {
        if (err.name === 'AbortError') {
            // Handle cancellation specifically
            console.log('Request was canceled');
        } else {
            // Handle other types of errors
            console.error('Request failed', err);
        }
    });

Enter fullscreen mode Exit fullscreen mode

Top comments (0)