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();
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
}
});
}
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();
};
}, []);
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;
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.
Top comments (1)
Сongratulations 🥳! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up 👍