I am trying to make exhaustMap to work, but am not able to. I want to be able to limit the number of api calls. Right now when I search and it's loading, and I type in another value in the input, the code makes a new api call. I want to limit this, so that this does not happen.
loadItems = () => {
const element: any = document.getElementById('type-ahead')
fromEvent(element, 'keyup')
.pipe(
debounceTime(200),
map((e: any) => e.target.value),
distinctUntilChanged(),
exhaustMap(() => interval(1000).pipe(take(10))), // doesnt work, i dont even know why im writing 10 here.
switchMap(this.requestProducts),
tap((data: any) => {
this.page = 1
this.parsedData = data
this.onViewPage()
})
)
.subscribe();
}
CodePudding user response:
If I understand your requirement correctly, and you wish to ignore all keyup
events until the HTTP API request for the current event is completed, you'd need only to switch the switchMap
with exhaustMap
and remove the current exhaustMap
.
loadItems = () => {
const element: any = document.getElementById('type-ahead')
fromEvent(element, 'keyup')
.pipe(
debounceTime(200),
map((e: any) => e.target.value),
exhaustMap(this.requestProducts.bind(this)), // <-- use `bind(this)` if you use `this` in `requestProducts()` to denote class member variables
tap((data: any) => {
this.page = 1;
this.parsedData = data;
this.onViewPage();
})
)
.subscribe();
}
- You could find differences b/n different RxJS higher order mapping operators here.
- Usage of
document.getElementById()
in Angular is discouraged since it would search the entire DOM of the app (and note Angular apps are SPA), instead of looking only in the specific component. There are multiple alternatives:- Refer this answer
- Use template reference variable
ViewChild
ElementRef
RxJSfromEvent
.
Working example: Stackblitz
Edit 1: Include working example