0

I am using an "in progress" indicator that is displayed as long as tasks are currently running. When starting a task, the tasks counter increases by 1 and decreases by 1 at the end of the task. Basically: if (count>0) displayIndicator().

When a new inner Observable is emitted, switchMap stops emitting items from the earlier-emitted inner Observable and begins emitting items from the new one.

The problem is, that disregarding earlier-emmited Observables does not trigger the counter that decreases this.uiService.indicator.task(-1).

init(): void {
    this.searchResults$: Observable<SearchResult[]> = this.searchTerms.pipe(

    // wait 700ms after each keystroke before considering the term
    debounceTime(700),

    // ignore new term if same as previous term
    distinctUntilChanged(),
      
    // switch to new search observable each time the term changes and discard previous (active) responses
    switchMap((searchTerm, i) => this.apiService.searchDB(searchTerm, i))
    );


    this.searchSubscription = this.searchResults$.subscribe({
      next: (response) => {
        console.log('received', response)
        this.uiService.indicator.task(-1);
      }
}
triggerSearch(term: string): void {
    this.searchTerms.next(term);
}
apiService.searchDB(searchTerm, i): Observable<SearchResult[]> {
    this.uiService.indicator.task(+1);
    ...
}

I've tried using the tap operator to catch it after switchMap, but it's not being triggered either since switchMap interrupts passing Observables when a new searchTerm is emitted.

Wilhelm Mauch
  • 23
  • 1
  • 6

1 Answers1

0

Try using the finalize operator inside the switchMap:


switchMap((searchTerm, i) => this.apiService.searchDB(searchTerm, i)).pipe(
  finalize(() => this.uiService.indicator.task(-1)
)

...

this.searchSubscription = this.searchResults$.subscribe((response) => console.log('received', response));

Untested as I'm on mobile.

wlf
  • 3,086
  • 1
  • 19
  • 29
  • Genius, it worked when I added it after the `searchDB()` instead of after `switchMap()` since "finalize" mirrors the source Observable. **Solution**:`this.searchTerms.pipe(...searchDB(...).pipe(finalize(...)))`. Thank you so much. – Wilhelm Mauch Mar 24 '23 at 14:39