Table of Contents
In my previous article, I have explained how to cancel previous requests in axios. In this article, we will see how to accomplish the same, while using fetch API
Setting up a mock API
First, let's set up a mock API so that we can query it. Install json-server globally using the following command:
1npm install -g json-server
Create a file named db.json
in a place of your choice with the following content:
1{"animals":[{"id":0,"name":"Aardvark"},{"id":1,"name":"Albatross"},{"id":2,"name":"Alligator"},{"id":3,"name":"Alpaca"},{"id":4,"name":"Ant"},{"id":5,"name":"Anteater"},{"id":6,"name":"Antelope"},{"id":7,"name":"Ape"},{"id":8,"name":"Armadillo"},{"id":9,"name":"Donkey"},{"id":10,"name":"Baboon"},{"id":11,"name":"Badger"},{"id":12,"name":"Barracuda"},{"id":13,"name":"Bat"},{"id":14,"name":"Bear"},{"id":15,"name":"Beaver"},{"id":16,"name":"Bee"},{"id":17,"name":"Bison"},{"id":18,"name":"Boar"},{"id":19,"name":"Buffalo"},{"id":20,"name":"Butterfly"},{"id":21,"name":"Camel"},{"id":22,"name":"Capybara"},{"id":23,"name":"Caribou"},{"id":24,"name":"Cassowary"},{"id":25,"name":"Cat"},{"id":26,"name":"Caterpillar"},{"id":27,"name":"Cattle"},{"id":28,"name":"Chamois"},{"id":29,"name":"Cheetah"},{"id":30,"name":"Chicken"},{"id":31,"name":"Chimpanzee"},{"id":32,"name":"Chinchilla"},{"id":33,"name":"Chough"},{"id":34,"name":"Clam"},{"id":35,"name":"Cobra"},{"id":36,"name":"Cockroach"},{"id":37,"name":"Cod"},{"id":38,"name":"Cormorant"},{"id":39,"name":"Coyote"},{"id":40,"name":"Crab"},{"id":41,"name":"Crane"},{"id":42,"name":"Crocodile"},{"id":43,"name":"Crow"},{"id":44,"name":"Curlew"},{"id":45,"name":"Deer"},{"id":46,"name":"Dinosaur"},{"id":47,"name":"Dog"},{"id":48,"name":"Dogfish"},{"id":49,"name":"Dolphin"},{"id":50,"name":"Dotterel"},{"id":51,"name":"Dove"},{"id":52,"name":"Dragonfly"},{"id":53,"name":"Duck"},{"id":54,"name":"Dugong"},{"id":55,"name":"Dunlin"},{"id":56,"name":"Eagle"},{"id":57,"name":"Echidna"},{"id":58,"name":"Eel"},{"id":59,"name":"Eland"},{"id":60,"name":"Elephant"},{"id":61,"name":"Elk"},{"id":62,"name":"Emu"},{"id":63,"name":"Falcon"},{"id":64,"name":"Ferret"},{"id":65,"name":"Finch"},{"id":66,"name":"Fish"},{"id":67,"name":"Flamingo"},{"id":68,"name":"Fly"},{"id":69,"name":"Fox"},{"id":70,"name":"Frog"},{"id":71,"name":"Gaur"},{"id":72,"name":"Gazelle"},{"id":73,"name":"Gerbil"},{"id":74,"name":"Giraffe"},{"id":75,"name":"Gnat"},{"id":76,"name":"Gnu"},{"id":77,"name":"Goat"},{"id":78,"name":"Goldfinch"},{"id":79,"name":"Goldfish"},{"id":80,"name":"Goose"},{"id":81,"name":"Gorilla"},{"id":82,"name":"Goshawk"},{"id":83,"name":"Grasshopper"},{"id":84,"name":"Grouse"},{"id":85,"name":"Guanaco"},{"id":86,"name":"Gull"},{"id":87,"name":"Hamster"},{"id":88,"name":"Hare"},{"id":89,"name":"Hawk"},{"id":90,"name":"Hedgehog"},{"id":91,"name":"Heron"},{"id":92,"name":"Herring"},{"id":93,"name":"Hippopotamus"},{"id":94,"name":"Hornet"},{"id":95,"name":"Horse"},{"id":96,"name":"Human"},{"id":97,"name":"Hummingbird"},{"id":98,"name":"Hyena"},{"id":99,"name":"Ibex"},{"id":100,"name":"Ibis"},{"id":101,"name":"Jackal"},{"id":102,"name":"Jaguar"},{"id":103,"name":"Jay"},{"id":104,"name":"Jellyfish"},{"id":105,"name":"Kangaroo"},{"id":106,"name":"Kingfisher"},{"id":107,"name":"Koala"},{"id":108,"name":"Kookabura"},{"id":109,"name":"Kouprey"},{"id":110,"name":"Kudu"},{"id":111,"name":"Lapwing"},{"id":112,"name":"Lark"},{"id":113,"name":"Lemur"},{"id":114,"name":"Leopard"},{"id":115,"name":"Lion"},{"id":116,"name":"Llama"},{"id":117,"name":"Lobster"},{"id":118,"name":"Locust"},{"id":119,"name":"Loris"},{"id":120,"name":"Louse"},{"id":121,"name":"Lyrebird"},{"id":122,"name":"Magpie"},{"id":123,"name":"Mallard"},{"id":124,"name":"Manatee"},{"id":125,"name":"Mandrill"},{"id":126,"name":"Mantis"},{"id":127,"name":"Marten"},{"id":128,"name":"Meerkat"},{"id":129,"name":"Mink"},{"id":130,"name":"Mole"},{"id":131,"name":"Mongoose"},{"id":132,"name":"Monkey"},{"id":133,"name":"Moose"},{"id":134,"name":"Mosquito"},{"id":135,"name":"Mouse"},{"id":136,"name":"Mule"},{"id":137,"name":"Narwhal"},{"id":138,"name":"Newt"},{"id":139,"name":"Nightingale"},{"id":140,"name":"Octopus"},{"id":141,"name":"Okapi"},{"id":142,"name":"Opossum"},{"id":143,"name":"Oryx"},{"id":144,"name":"Ostrich"},{"id":145,"name":"Otter"},{"id":146,"name":"Owl"},{"id":147,"name":"Oyster"},{"id":148,"name":"Panther"},{"id":149,"name":"Parrot"},{"id":150,"name":"Partridge"},{"id":151,"name":"Peafowl"},{"id":152,"name":"Pelican"},{"id":153,"name":"Penguin"},{"id":154,"name":"Pheasant"},{"id":155,"name":"Pig"},{"id":156,"name":"Pigeon"},{"id":157,"name":"Pony"},{"id":158,"name":"Porcupine"},{"id":159,"name":"Porpoise"},{"id":160,"name":"Quail"},{"id":161,"name":"Quelea"},{"id":162,"name":"Quetzal"},{"id":163,"name":"Rabbit"},{"id":164,"name":"Raccoon"},{"id":165,"name":"Rail"},{"id":166,"name":"Ram"},{"id":167,"name":"Rat"},{"id":168,"name":"Raven"},{"id":169,"name":"Red deer"},{"id":170,"name":"Red panda"},{"id":171,"name":"Reindeer"},{"id":172,"name":"Rhinoceros"},{"id":173,"name":"Rook"},{"id":174,"name":"Salamander"},{"id":175,"name":"Salmon"},{"id":176,"name":"Sand Dollar"},{"id":177,"name":"Sandpiper"},{"id":178,"name":"Sardine"},{"id":179,"name":"Scorpion"},{"id":180,"name":"Seahorse"},{"id":181,"name":"Seal"},{"id":182,"name":"Shark"},{"id":183,"name":"Sheep"},{"id":184,"name":"Shrew"},{"id":185,"name":"Skunk"},{"id":186,"name":"Snail"},{"id":187,"name":"Snake"},{"id":188,"name":"Sparrow"},{"id":189,"name":"Spider"},{"id":190,"name":"Spoonbill"},{"id":191,"name":"Squid"},{"id":192,"name":"Squirrel"},{"id":193,"name":"Starling"},{"id":194,"name":"Stingray"},{"id":195,"name":"Stinkbug"},{"id":196,"name":"Stork"},{"id":197,"name":"Swallow"},{"id":198,"name":"Swan"},{"id":199,"name":"Tapir"},{"id":200,"name":"Tarsier"},{"id":201,"name":"Termite"},{"id":202,"name":"Tiger"},{"id":203,"name":"Toad"},{"id":204,"name":"Trout"},{"id":205,"name":"Turkey"},{"id":206,"name":"Turtle"},{"id":207,"name":"Viper"},{"id":208,"name":"Vulture"},{"id":209,"name":"Wallaby"},{"id":210,"name":"Walrus"},{"id":211,"name":"Wasp"},{"id":212,"name":"Weasel"},{"id":213,"name":"Whale"},{"id":214,"name":"Wildcat"},{"id":215,"name":"Wolf"},{"id":216,"name":"Wolverine"},{"id":217,"name":"Wombat"},{"id":218,"name":"Woodcock"},{"id":219,"name":"Woodpecker"},{"id":220,"name":"Worm"},{"id":221,"name":"Wren"},{"id":222,"name":"Yak"},{"id":223,"name":"Zebra"}]}
Open the directory where db.json
is stored in a command prompt and run the following command:
1json-server -p 4000 db.json --delay 3000
Here have created a mock API endpoint at port 4000 with a delay of 3s. You can access it by opening http://localhost:4000/animals
JavaScript Implementation
Let's first see how to implement cancelling in JavaScript.
Create a file named search.html
with the following content and open it in the browser
1<!DOCTYPE html>2<html lang="en">3 <head>4 <meta charset="UTF-8" />5 <meta http-equiv="X-UA-Compatible" content="IE=edge" />6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />7 <title>Search Page</title>8 </head>9 <style>10 body {11 margin-top: 10px;12 }13 .search-wrapper {14 display: flex;15 justify-content: center;16 }17 </style>1819 <script>20 const search = () => {21 const inputElement = document.querySelector("#search")22 const searchValue = inputElement.value?.trim()23 if (searchValue) {24 fetch("http://localhost:4000/animals?q=" + searchValue)25 .then(response => response.json())26 .then(data => console.log("Results for " + searchValue, data))27 .catch(err => {28 console.log(err)29 })30 }31 }32 </script>33 <body>34 <div class="search-wrapper">35 <input36 type="text"37 name="search"38 id="search"39 placeholder="Type query..."40 onkeyup="search()"41 />42 </div>43 </body>44</html>
In the above code, we have a text box and when the user types something in the text box we call the mock API.
If you open the app in your browser and type cat
in the search box, you will see that the API is getting called thrice:
Since the API is slow and user will finish typing cat
even before the result for c
is received,
we can cancel the previous request if the search term is changed.
1<!DOCTYPE html>2<html lang="en">3 <head>4 <meta charset="UTF-8" />5 <meta http-equiv="X-UA-Compatible" content="IE=edge" />6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />7 <title>Search Page</title>8 </head>9 <style>10 body {11 margin-top: 10px;12 }13 .search-wrapper {14 display: flex;15 justify-content: center;16 }17 </style>1819 <script>20 const search = () => {21 const inputElement = document.querySelector("#search")22 const searchValue = inputElement.value?.trim()23 if (searchValue) {24 if (window.controller) {25 window.controller.abort()26 }27 window.controller = new AbortController()28 window.signal = window.controller.signal2930 fetch("http://localhost:4000/animals?q=" + searchValue, {31 signal: signal,32 })33 .then(response => response.json())34 .then(data => console.log("Results for " + searchValue, data))35 .catch(err => {36 console.log(err)37 })38 }39 }40 </script>41 <body>42 <div class="search-wrapper">43 <input44 type="text"45 name="search"46 id="search"47 placeholder="Type query..."48 onkeyup="search()"49 />50 </div>51 </body>52</html>
In the above code, we are creating an AbortController, which can be used to cancel the web requests and passing the AbortSignal instance received from it to the fetch API.
When the next request arrives, if the controller exists, then we are calling the abort()
function to cancel the previous request.
If you search for cat
and check the network tab, you will see the previous requests being canceled:
React Implementation
You can achieve the same in React using the following code:
1import { useState } from "react"23let controller, signal4function App() {5 const [searchTerm, setSearchTerm] = useState("")67 const search = e => {8 const value = e.target.value9 setSearchTerm(value)10 if (value?.trim()) {11 if (controller) {12 controller.abort()13 }14 controller = new AbortController()15 signal = controller.signal1617 fetch("http://localhost:4000/animals?q=" + value, {18 signal: signal,19 })20 .then(response => response.json())21 .then(data => console.log("Results for " + value, data))22 .catch(err => {23 console.log(err)24 })25 }26 }27 return (28 <div className="App">29 <input30 type="text"31 name="search"32 onChange={search}33 placeholder="Type query..."34 value={searchTerm}35 />36 </div>37 )38}3940export default App
Source code
You can view the source code of the app here.
Do follow me on twitter where I post developer insights more often!