If I get enough users on my application, sending an ajax request with each keystroke is an effective way to bring the server to its knees (not to mention possibly making the client application feel quite sluggish). On implementing a symbol search box with two options (DB Search and Web Api Search). While I am typing the symbol (ex: AAPL - aple stock) in the search box the fetch()
request is sent each time over the network. To avoid it I tried to use setTimeout()
but fetch()
request is sent multiple times, anyway. How to delay/start/debounce fetching the request until user stops typing in input area to send only one fetch()
request?
HTML:
<label for="symbolTags">Symbol: </label>
<input type="text" id="symbolTags" name="symbol">
<label for="api">Select Search Api: </label>
<select id="api" name="routes_api">
<option value="search">Web Search Api</option>
<option value="dbsearch">DB Search Api</option>
</select>
JavaScript:
const symbolTags = document.querySelector('#symbolTags')
const symbolTagsOptions = document.querySelector('#api')
const urlsObject = {
dbsearch: '/dbsearch/',
search: '/search/'
}
symbolTags.oninput = function () {
let symbolTagsOptionsValue = symbolTagsOptions.value
let arg = urlsObject[symbolTagsOptionsValue]
// Init a timeout variable to be used below
let timeout = null
// Clear the timeout if it has already been set.
// This will prevent the previous task from executing
// if it has been less than <MILLISECONDS>
clearTimeout(timeout)
// Make a new timeout set to go off in 2000ms
timeout = setTimeout(function () {
requestSymbolSearch(arg)
}, 2000)
}
function requestSymbolSearch(arg) {
getData(arg)
.then(data => {
console.log(data)
$('#symbolTags').autocomplete({
source: data.map(item => item.symbol),
autoFocus: true
})
})
.catch(error => console.error('Error:', error))
}
function getData(url) {
let curValueSymbol = symbolTags.value
let urlPlus = `${url}${curValueSymbol}`
console.log(urlPlus)
return fetchData(urlPlus)
}
async function fetchData(urlPlus) {
const dataResponse = await fetch(urlPlus)
const dataJson = await dataResponse.json()
return dataJson
}
Here is the console result:
Here is the network result: