I'm implementing a simple search bar that calls an asyncronous method which is populating a display list that is to be displayed as the user types. The issue I'm running into is that every key press triggers another call of the async method, and occasionally the earlier key presses will return after the following key presses, resulting in the display array being populated with results that aren't accounting for later key presses.
For example if a user is typing the word "Dog", the async method "search" will trigger three times, once for "D" once for "Do" and once for "Dog". If the results for "D" return after the results for "Dog" (which is likely, given that there are more results for the shorter search strings), then the final array will be populated with all matches of "D", rather than "Dog".
How can make it so that the final results are always from the last called instance of async search method?
CodePudding user response:
This is a common problem solved by Observables
, debounce
and the switchMap
operator. In Angular it is advised to use Obserables
instead of async/await
.
obserable.pipe(
debounceTime(200),
switchMap(input => {
// return async http call here
})
).subscribe(result => {
// update UI
})
The switchMap
guarantees that older events are cancelled when the Observable
triggers again. So you will always only see the result of the latest request. The debounceTime
will limit the amount of requests to a maximum of 1
request per 200
milliseconds.
CodePudding user response:
Async Await Example click here
Or your input like
<input placeholder="Search" (keyup.backspace)="onSearchKeyUp($event)" (keyup.enter)="onSearchKeyUp($event)">