JavaScript  

How to Cancel Fetch Requests in JavaScript Using AbortController

Introduction

In modern web development, making API calls using fetch() is common. But what happens when a user navigates away, types too quickly in a search bar, or triggers multiple requests before the first one finishes? If not handled properly, these lingering API requests can cause performance issues, data conflicts, and memory leaks.

That’s where AbortController comes in.

In this article, you'll learn how to cancel fetch requests in JavaScript using the AbortController API with easy-to-follow examples.

What is AbortController?

AbortController is a built-in JavaScript API that allows you to cancel ongoing asynchronous operations—especially fetch() requests—gracefully.

It provides a signal that can be passed to a fetch call, and this signal can be triggered to abort the request when needed.

Basic Syntax

const controller = new AbortController();
const signal = controller.signal;

fetch('https://api.example.com/data', { signal })
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('Fetch request was cancelled');
    } else {
      console.error('Fetch failed', error);
    }
  });

// Cancel the request after 2 seconds
setTimeout(() => {
  controller.abort();
}, 2000);

What Happens Here?

  • controller.abort() cancels the request.

  • The fetch promise is rejected with an AbortError.

Real-World Use Case: Cancel Search Requests

Let’s build a debounced search box that cancels the previous fetch if a new character is typed quickly.

<input type="text" id="searchBox" placeholder="Search..." />
<div id="results"></div>
let controller;

document.getElementById('searchBox').addEventListener('input', function () {
  const query = this.value.trim();
  const resultsDiv = document.getElementById('results');

  // Cancel previous request
  if (controller) controller.abort();

  controller = new AbortController();

  if (query === '') {
    resultsDiv.innerHTML = '';
    return;
  }

  fetch(`https://api.example.com/search?q=${query}`, {
    signal: controller.signal
  })
    .then(res => res.json())
    .then(data => {
      resultsDiv.innerHTML = JSON.stringify(data);
    })
    .catch(err => {
      if (err.name === 'AbortError') {
        console.log('Previous search cancelled');
      } else {
        console.error('Fetch error:', err);
      }
    });
});

Why This Is Useful

  • Prevents flooding the server with unnecessary calls.

  • Keeps only the latest request active.

  • Improves user experience and app performance.

Handling Errors Gracefully

Whenever you cancel a fetch request using AbortController, an AbortError is thrown. It’s important to check the error type so that your app doesn’t show unnecessary error messages.

.catch(error => {
  if (error.name === 'AbortError') {
    // No problem, we intentionally aborted
  } else {
    console.error('Something went wrong:', error);
  }
});

Use Cases for AbortController

  • Debounced search inputs

  • Cancelling image or file downloads

  • Aborting fetch on component unmount (in React/Vue)

  • Preventing race conditions in async flows

Browser Support

AbortController is supported in all modern browsers (Chrome, Firefox, Edge, Safari). It is not supported in Internet Explorer.

Final Thoughts

The AbortController API is an elegant and native solution to a common problem in asynchronous JavaScript. By learning to use it, you can write more efficient, user-friendly, and bug-resistant code.

Start using it today in your fetch requests, especially in scenarios where cancellation improves UX—like search boxes, dropdown filters, or any async interaction that can change rapidly.