Home > database >  How do I limit the api calls with exhaust map?
How do I limit the api calls with exhaust map?

Time:05-09

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();
}
  1. You could find differences b/n different RxJS higher order mapping operators here.
  2. 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 RxJS fromEvent.

Working example: Stackblitz

Edit 1: Include working example

  • Related