0

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();
  }
user14850280
  • 389
  • 3
  • 16

1 Answers1

3

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

ruth
  • 29,535
  • 4
  • 30
  • 57
  • hey, its still making additional api calls after 200ms wait time on slow 3g. i only want ONE request. – user14850280 May 09 '22 at 08:02
  • Do you want that behavour like in the example from the official documentation of [exhaustMap](https://rxjs-dev.firebaseapp.com/api/index/function/exhaustMap) which can be found here: https://stackblitz.com/run?devtoolsheight=50&file=index.ts ? – daflodedeing May 09 '22 at 08:29
  • @user14850280: I've included a Stackblitz in the post. It seems to work there, also with reduced `debounceTime` values. If the error still persists for you, you might have to provide more information. – ruth May 09 '22 at 08:43