I have a method that will search for employee's based on a search term.
this._sub.pipe(
debounceTime(500),
filter(x => !!x),
distinctUntilChanged(),
switchMap(this.getResults.bind(this))
).subscribe((d: IDisplayEmp[]) => {
console.log('RES', d)
this.displayResults = d;
});
this._sub.next('mySearchTerm');
This works great, previous API calls are cancelled if a new one is issued. However here comes the issue.
Active API calls are only cancelled when the debounce has emitted. If an active API call returns whilst the debounce is waiting it still triggers my subscribe.
I understand this is because the cancelling only happens within the scope of the switchmap.
Is possible to refactor this so that if the debounce is waiting for input to stop it will cancel any pending API calls?
Probably a naive approach but i attempted something like below, it emits values but now there is no debounce in effect.
this._sub.pipe(
filter(x => !!x),
distinctUntilChanged(),
switchMap((x) => {
return of(x)
.pipe(
debounceTime(500),
this.getResults.bind(this)
);
})
).subscribe((d: IDisplayEmp[]) => {
console.log('RES', d)
this.displayResults = d;
});
Thanks for any help.
Use takeUntil to cancel your requests whenever this._sub emits.
this._sub.pipe(
debounceTime(500),
filter(x => !!x),
distinctUntilChanged(),
switchMap(searchTerm => this.getResults(searchTerm).pipe(
takeUntil(this._sub)
))
).subscribe((d: IDisplayEmp[]) => {
console.log('RES', d)
this.displayResults = d;
});
The accepted answer should work fine, but I wanted to share another way you can do this with timer instead of debounceTime:
this._sub.pipe(
filter(x => !!x),
distinctUntilChanged(),
switchMap(val => timer(500).pipe(
switchMap(() => this.getResults(val))
))
).subscribe(...);
Now, if an emissions reaches switchMap, the timer and everything in it (including an active network request) will be canceled, and a new timer will be created.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With