How to cancel a fetch request?
Ever wondered how to cancel a fetch request in your web application. There’s good news, we can finally abort HTTP calls made using fetch from our applications. In this article, I will cover how to abort or cancel an HTTP call made using fetch(). I will also walk you through a sample example with details.
What is fetch()?
Using fetch you can make HTTP/Network calls from your JavaScript based application. It can be your web application or even a React Native mobile application. Fetch is a modern JavaScript API that replaces the old XMLHttpRequest (XHR) API. Fetch is basically a promised based implementation which makes it asynchronous by default. That means the browser will not freeze and the Javascript main thread is not blocked while you make the call and the response gets back to your browser. The Javascript engine will continue to run other tasks. And your browser can take user inputs while the request/response cycle happens asynchronously.
The good thing about fetch is that since it is Promise based, so no callback hell. Also, it is simpler and cleaner to use online XMLHttpRequest.
Let’s see a quick example. I will not go into details of fetch in this article. I have added few comments in the code sample below for your understanding.
async function makeCall() {
const URL = 'https`;//reqres.in/api/users'; //fake JSON api
try {
const response = await fetch(URL); //makes a GET call
const data = await response.json(); //waits for the promise to resolve
console.log(data);
}
catch(err) {
//handle errors like 400, 500 etc
console.log('error: ', err);
}
}
makeCall();
What is the need to cancel a fetch request?
There can be various reasons, but the most obvious to me are listed below,
- Your network call has a timeout period. So if the response does not come back within that time period you abort the call and tell the browser to stop whatever he was doing. By default fetch() API does not support timeouts.
- Say, your user is browsing a page on your application. That page makes fetch calls to retrieve new data which then is rendered onto the page. Now, the user navigated onto a different page as he was no longer interested in the current page. What happens to the fetch calls that were already made from the current page? Well, we can abort it right.
How to cancel a fetch request?
Alright, so to cancel a fetch request, we have two separate API’s available to us – AbortController and AbortSignal. Don’t be overwhelmed by the names, they are simple and easier to use. Let’s see an example,
First we need to create an AbortController instance. We will be using this instance when we want to cancel the fetch request
let abortController = new AbortController();
And then from the AbortController object, we can create an AbortSignal instance. The AbortSignal instance will be used when we make our fetch request.
const signal = abortController.signal;
Now that we have the necessary items, let’s check out how you can cancel a fetch request. I have a function below that makes an HTTP fetch call.
const URL = 'https://reqres.in/api/users?delay=5'; //delay for 5secs
let abortController = null;
const makeCall = async () => {
abortController = new AbortController(); //create a new instance everytime
const signal = abortController.signal;
try {
const response = await fetch(URL, {
method: 'GET',
signal: signal //this is where we pass signal object
});
const data = await response.json();
console.log(data);
} catch(err) {
//handle errors for anything other than HTTP 200
//eg. 400, 500 errors will come here
console.log('Error: ', err);
}
}
makeCall();
If you notice in the code sample above, we need to pass our AbortSignal object inside the fetch() method as part of its options object.
await fetch(URL, options);
The catch however is that every time you make a new fetch request, you need to create a new instance of the AbortController and then derive a signal from it.
Now, while the request is in progress, you can cancel or abort it by calling the abort() method available with the AbortController object. You can put the code below in your custom event listener. For eg. a button click.
abortController && abortController.abort();
This is how your browser (Chrome) network panel will look like when you cancel the fetch request.
Also when you cancel a fetch request which was in progress, the Promise will reject with DOMException. You can see the error message since we handled it in the catch() block.
Error: DOMException: The user aborted a request.
Browser Support
The fetch api is widely supported across all major browsers. So it is very very safe to use. If you are still using jQuery $.ajax(), you can go ahead and try the native fetch api.
AbortController and AbortSignal API’s are also widely supported by the latest versions of all major browsers. Again, safe to use without any fallbacks or polyfills. Refer to the image below. Source – caniuse.