Cancel rest API pending request
As we know, fetch
returns a promise. And JavaScript generally has no concept of aborting/canceling a promise
. So how can we cancel an ongoing fetch?
E.g. if the user actions on our site indicate that the fetch isn’t needed anymore.
There’s a unique built-in object for such purposes: AbortController
. It can be used to abort not only fetch
also other asynchronous tasks as well.
Let’s start with the creation on AbortController
.
The AbortController object
let controller = new AbortController();
Note: If you are working on React, Angular or any other JS framework try to define its top of the file. Because sometimes you will not get an updated value in runtime.
A controller is a very simple object.
1). It has a single method abort()
only.
2). And a single property signal
that allows you to set event listeners on it.
If you are familiar with JavaScript event listener, it’s very easy to understand for you.
when abort()
is called:
controller.signal
emits theabort
event andcontroller.signal.aborted
is becometrue
Let’s understand with example.
So first take a variable at the top of file.
let controller = null
Now create a async
function for API calling
const fetchTodo = async () => {
try {
const response = await fetch("www.example.com")
} catch (error){
alert(error)
}
}
Now target an element for callingfetchTodo
function. And call fetchTodo
{
const targetedElement = document.getElementById("load-todo");
targetedElement.addEventListener('click', () => {
fetchTodo();
})
}
You about to call your fetch request now. You need to abort
it, so let’s update fetchTodo
.
You need to setup single in fetchTodo
so you can manually abort
your API request. Let’s see how you can do it?
You can send two params in fetch
url and one request object, you need to get signal
as fetchTodo() params and pass it in fetch request.
const fetchTodo = async (signal) => {
try {
const response = await fetch("www.example.com", {
signal: signal
})
} catch (error){
alert(error)
}
}
In this step you setup signal in fetch
request, now if you call the request and request is in pending
step, and if you abort
the signal
request will be canceled automatically.
How you can abort signal?
Let’s go back to target step, here you are calling fetchTodo
so you just need to setup AbortController
in this step.
{
const targetedElement = document.getElementById("load-todo");
targetedElement.addEventListener('click', () => {
// In the first time controller is null
if(controller){
controller.abort();
controller = null
}
// Now set controller
controller = new AbortController();try {
// Here passing signal in fetchTodo
await fetchTodo(controller.signal);
} catch (error) {
console.log(error)
} finally {
// once request is completed controller will be in initial step
controller = null
}
})
}
Great!, you are done now 👏.
Lets assemble all code in single file.
{
let controller = null;
const fetchTodo = async (signal) => {
try {
const response = await fetch("www.example.com", {
signal: signal
})
} catch (error){
alert(error)
}
} const targetedElement = document.getElementById("load-todo"); targetedElement.addEventListener('click', () => {
// In the first time controller is null
if(controller){
controller.abort();
controller = null
}
// Now set controller
controller = new AbortController(); try {
// Here passing signal in fetchTodo
await fetchTodo(controller.signal);
} catch (error) {
console.log(error)
} finally {
// once request is completed controller will be in initial step
controller = null
}
})
}