Search code examples
rxjsrxjs6

How to start processing after the user finishes typing with RxJS?


I have an input element, where I want to show an autocomplete solution. I try to control the HTTP request's number with RxJS. I want to do: the HTTP request start only after 1 second of the user stop the typing.

I have this code:

of(this.inputBox.nativeElement.value)
  .pipe(
    take(1),
    map((e: any) => this.inputBox.nativeElement.value),
    // wait 1 second to start
    debounceTime(1000),
    // if value is the same, ignore
    distinctUntilChanged(),
    // start connection
    switchMap(term => this.autocompleteService.search({
      term: this.inputBox.nativeElement.value
    })),
  ).subscribe((result: AutocompleteResult[]) => {
    console.log(result);
  });

The problem is the debounceTime(1000) didn't wait to continue the pipe. The switchMap start immediately after every keyup event.

How can I wait 1 second after the user finishes typing?


Solution

  • The problem is that your chain starts with of(this.inputBox.nativeElement.value).pipe(take(1), ...) so it looks like you're creating a new chain (with a new debounce timer) on every single key press.

    Instead you should have just one chain and push values to its source:

    const keyPress$ = new Subject();
    
    ...
    
    keyPress$
      .pipe(
        debounceTime(1000),
        ...
      )
    
    ...
    
    keyPress$.next(this.inputBox.nativeElement.value);