I have the following search bar with
<div class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search Products" aria-label="Search" id="searchProduct">
</div>
I would like to fire an onInput event whenever user types it will call an API.
const debounce = (fn, delay = 1000) => {
let timerId = null;
return (...args) => {
clearTimeout(timerId);
timerId = setTimeout(() => fn(...args), delay);
};
};
let controller = new AbortController();
let signal = controller.signal;
const fetchProducts = (value, signal) => {
axios
.get(`/FYP-ECOMMERCE/api/products?search=${value}`, {
signal, // Pass the AbortSignal to the request
})
.then((response) => {
return response.data;
})
.then((data) => {
console.log(data);
})
.catch((error) => {
if (error.name === "AbortError") {
// Handle the request abortion (e.g., ignore or log it)
console.log("Request was aborted");
} else {
// Handle other errors
console.error("An error occurred:", error);
}
});
};
const onInput = debounce(fetchProducts, 500);
const searchBar = document.getElementById("searchProduct");
searchBar.addEventListener("input", (e) => {
const term = e.target.value;
if (term !== "") {
controller.abort();
controller = new AbortController();
signal = controller.signal;
onInput(e.target.value, signal);
}
});
So my question how to combine debounce and abortcontroller , so that the previous request gets aborted.
Thank you
2
Answers
fethcProducts
fn === create a new controller for each requestthis will give you control over the controller
onInput
a general function, add controller as param so that if controller exists, the current request will be aborted and fetch again with a new controllerthe onInput clearly can be written in a better way, but for now, I think this should do
Within your approach, the
onInput
will be called every time user click button. However, thanks todebounce
, the truthfetchProducts
will be called only once every 500ms and no more.Therefore if you just simply need to call "abort" at the beginning of
fetchProducts
You can learn more about it with the example from MDN
https://developer.mozilla.org/en-US/docs/Web/API/AbortController
Bonus:
Since the
controller
is outside the fetch function, if you have aCancel
/Abort
button, just simply do the same