Link copied!
Mastering AbortController: How to Cancel JavaScript Fetch API Requests Technical Log

TechiesAIE Journal

Mastering AbortController: How to Cancel JavaScript Fetch API Requests

TechiesAIE
TechiesAIE
Lead Developer · TechiesAIE
3 min read 652 words

Based on the sources linked below.

Cover image: Aboutbigdata · CC BY-SA 4.0 · License · Image source

To cancel an ongoing Fetch API request in JavaScript, you utilize the AbortController interface. This object allows you to create a signal that can be associated with one or more web requests, providing a mechanism to programmatically abort them when no longer needed. This functionality is crucial for managing asynchronous operations, preventing resource waste, and improving user experience by allowing users to stop long-running fetches.

How AbortController Works

The AbortController acts as a control plane for abortable operations. When you create an instance of AbortController, it automatically generates an associated AbortSignal object. This signal is what you pass to the `fetch()` function. When the `abort()` method is called on the controller, it triggers the signal, which then causes any `fetch()` requests listening to that signal to be aborted.

The `fetch()` API, being promise-based, will reject the promise with an `AbortError` exception if the request is canceled. This allows you to catch the cancellation specifically and handle it gracefully within your application logic. It's important to differentiate this from network errors or server-side issues, as an `AbortError` signifies a client-initiated cancellation.

Steps to Implement Request Cancellation

1. Create an AbortController Instance

First, instantiate a new `AbortController` object. This object will be responsible for sending the cancellation signal.

```javascript const controller = new AbortController(); ```

2. Attach the AbortSignal to Your Fetch Request

When making a `fetch()` call, include an `options` object with a `signal` property set to the `AbortSignal` generated by your controller. The `AbortSignal` is accessible via `controller.signal`.

```javascript async function fetchData() { try { console.log("Starting fetch"); const response = await fetch("https://example.org/get", { signal: controller.signal, }); console.log(`Response: ${response.status}`); } catch (e) { if (e.name === 'AbortError') { console.error("Fetch aborted:", e.message); } else { console.error("Fetch error:", e); } } } ```

3. Call abort() to Cancel the Request

When you want to cancel the request, simply call the `abort()` method on your `AbortController` instance. This will immediately trigger the cancellation for any `fetch()` requests associated with that controller's signal.

```javascript function cancelFetch() { controller.abort(); console.log("Canceled fetch"); } ```

Practical Example

Consider a scenario where a user navigates away from a page or closes a modal before a large data fetch completes. Using `AbortController`, you can prevent unnecessary network activity and update pending UI states appropriately.

```javascript const fetchButton = document.createElement('button'); fetchButton.textContent = 'Start Fetch'; document.body.appendChild(fetchButton); const cancelButton = document.createElement('button'); cancelButton.textContent = 'Cancel Fetch'; document.body.appendChild(cancelButton); let currentController = null; fetchButton.addEventListener('click', async () => { if (currentController) { currentController.abort(); // Abort previous fetch if still active } currentController = new AbortController(); const signal = currentController.signal; try { console.log('Starting fetch...'); const response = await fetch('https://example.org/products.json', { signal }); if (!response.ok) { throw new Error(`Response status: ${response.status}`); } const data = await response.json(); console.log('Fetch completed:', data); } catch (error) { if (error.name === 'AbortError') { console.log('Fetch successfully aborted.'); } else { console.error('Fetch error:', error); } } }); cancelButton.addEventListener('click', () => { if (currentController) { currentController.abort(); console.log('Fetch operation canceled.'); currentController = null; } }); ```

In this example, clicking 'Start Fetch' initiates a request, and clicking 'Cancel Fetch' stops it. If a fetch is already in progress when 'Start Fetch' is clicked again, the previous fetch is aborted before a new one begins, ensuring only the latest operation proceeds.

Important Considerations

It's important to note that `AbortController` can also abort the consumption of response bodies. If `fetch()` is fulfilled, but the `abort()` method is called before methods like `response.json()` or `response.text()` complete, then attempting to read the response body will also reject with an `AbortError` exception. This ensures that even post-response processing can be halted.

The `AbortController` interface is widely supported across modern browsers and is available in Web Workers, making it a robust solution for managing HTTP requests in various JavaScript environments. Its integration with the promise-based `fetch()` API provides a cleaner and more modern approach compared to the older `XMLHttpRequest` callback-based methods, allowing for more readable and maintainable asynchronous code.

Sources