DEV Community

Cakra Danu Sedayu
Cakra Danu Sedayu

Posted on

Cancel HTTP Request by Using AbortController in Web App

Why?

In a simple way, it is to optimize our Website Performance by controlling ongoing HTTP requests, for example, users leave the page when a HTTP request is running, users want to stop their download/upload file, and many more depending on your app. So, this article may help you or me (in the future) to understand and know how to Cancel our HTTP Request with AbortController in a web Application.

Abort Controller?

According to MDN:

The AbortController interface represents a controller object that allows you to abort one or more Web requests as and when desired.

AbortController is a Class that has one instance properties and one instance methods, the instance property is signal and the instance method is abort. The AbortController is supported in almost all browsers except IE (but, who cares -_-).

Example

Here simple explanation how to use it:

// declare 
const controller = new AbortController();

// get signal
const signal = controller.signal;

// put signal in fetch or axios options
fetch(API, { signal });
axios(API, { signal });

// cancel request
controller.abort();
Enter fullscreen mode Exit fullscreen mode

Cancel fetch in HTTP Request

In case we have a feature that can download a BIG file. To make it user-friendly, we should provide a cancel button.

let controller;

const abortBtn = document.querySelector(".abort");

abortBtn.addEventListener("click", () => {
  if (controller) {
    controller.abort();
    console.log("Download aborted");

    // Reset new AbortController, so we can do re-fetch
    controller = new AbortController();
  }
});

function fetchVideo() {
  controller = new AbortController();
  const signal = controller.signal;

  fetch(url, { signal })
    .then((response) => {
      console.log("Download complete", response);
    })
    .catch((err) => {
      if (err.name === 'AbortError') {
        console.log('successfully aborted');
      } else {
        // handle error
      }
    });
}
Enter fullscreen mode Exit fullscreen mode

Cancel Request when useEffect Clean Up

The most popular AbortController usage is to clean up the useEffect function in react.js. FYI, starting from v0.22.0 Axios supports AbortController to cancel requests, and CancelToken is deprecated.

useEffect(() => {
  const controller = new AbortController();
  const source = controller.signal;

  axios
    .get(API, { signal })
    .catch((err) => {
      if (error.name === "CanceledError") {
        console.log('successfully aborted');
      } else {
        // handle error
      }
    });
  return () => {
    // cancel the request before component unmounts
    source.cancel();
  };
}, []);
Enter fullscreen mode Exit fullscreen mode

One of the important thing is, errName in axios is CanceledError and in fetch is AbortError.

Cancel fetch Request in TypeScript react.js

this example is not really different from the first example, but sometimes we can adopt 100% js code to react.js code. And in TypeScript, sometimes, it makes more challenging to use the correct type in, what should type I use, where to find the docs, etc (:

import { useRef } from "react";

function Component() {
  const abortControllerRef = useRef<AbortController>(new AbortController());

  const onAbortFetch = () => {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      console.log("Download aborted");

      // Reset new AbortController, so we can do re-fetch
      abortControllerRef.current = new AbortController();
    }
  };

  function getFile() {
    const signal = abortControllerRef.current.signal;

    fetch(API, { signal })
      .then((response) => {
        console.log("Download complete", response);
      })
      .catch((err) => {
        if (err.name === "AbortError") {
          console.log("successfully aborted");
        } else {
          // handle error
        }
      });
  }

  return (
    <>
      <button onClick={getFile}>Get File</button>
      <br />
      <br />
      <button onClick={onAbortFetch}>Abort</button>
    </>
  );
}

export default Component;
Enter fullscreen mode Exit fullscreen mode

Here the gist link , I'm not embed here cause the gist preview only show one line only.

Conclusion

An instance of the AbortController class exposes the abort method and the signal property. Put the signal in options of fetch or axios then called the abort method whenever you want to cancel the HTTP request.

Source:

Top comments (1)

Collapse
 
fruntend profile image
fruntend

Сongratulations 🥳! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up 👍