JAVASCRIPT

Cancelling Fetch Requests with AbortController

Improve user experience and prevent race conditions by learning to cancel pending `fetch` API requests using `AbortController` in JavaScript, especially useful for search or navigation.

let currentController = null; // To keep track of the last controller for cancellation

async function fetchDataWithCancellation(url, options = {}) {
  if (currentController) {
    currentController.abort(); // Abort previous pending request
    console.log('Previous request aborted.');
  }

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

  try {
    const response = await fetch(url, { ...options, signal });
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const data = await response.json();
    currentController = null; // Clear controller once request is complete
    return data;
  } catch (error) {
    if (error.name === 'AbortError') {
      console.log('Fetch request was aborted.');
    } else {
      console.error('Fetch error:', error);
      throw error;
    }
    currentController = null; // Clear controller on error or abort
  }
}

// Example Usage:
// // Simulating rapid calls, e.g., a type-ahead search
// const searchInput = document.getElementById('search-box');
// searchInput.addEventListener('input', debounce(async (event) => {
//   const query = event.target.value;
//   if (query.length > 2) {
//     try {
//       const data = await fetchDataWithCancellation(`https://api.example.com/search?q=${query}`);
//       console.log('Search results:', data);
//       // Render results
//     } catch (error) {
//       // Handle aborted or other errors
//     }
//   }
// }, 300)); // Using a debounce function to limit API calls

// // Debounce helper function (not part of the core snippet but often used with AbortController)
// function debounce(func, delay) {
//   let timeout;
//   return function(...args) {
//     const context = this;
//     clearTimeout(timeout);
//     timeout = setTimeout(() => func.apply(context, args), delay);
//   };
// }
How it works: This snippet demonstrates how to use `AbortController` to cancel pending `fetch` requests. Before making a new request, it checks if a previous one is still active and aborts it. This is crucial for scenarios like type-ahead search or tab switching where multiple requests might be fired rapidly, preventing stale responses and reducing unnecessary network traffic, thereby improving user experience.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs