kajl16
kajl16

Reputation: 27

Is there a way to call the onkeypress event after a second so that it wouldn't fire a method a bunch of times?

I'm writing a program that calls a method which shows data on a table using a textbox. The problem is that it calls the program more than 10 times each time. Is there a way to avoid this?

Here's the text box:

<input #input matInput placeholder="Search data" (keyup)="onKeypressEvent($event)">

Here's the method I'm calling:

  onKeypressEvent(event: any){
    fromEvent(this.input.nativeElement,'keyup')
        .pipe(
            debounceTime(150),
            distinctUntilChanged(),
            tap(() => {
                this.paginator.pageIndex = 0;
                this.loadData();
            })
        )
        .subscribe();
  }

Upvotes: 0

Views: 727

Answers (2)

Yuva Raj
Yuva Raj

Reputation: 3881

As per your existing code, it looks like you are using @viewChild().

Here is the simple & working solution. This avoids the additional Subject to use.

ngAfterViewInit() {
    fromEvent(this.input.nativeElement, "keyup")
      .pipe(debounceTime(1000)) // Update the debouceTime as per your wish
      .subscribe((val: KeyboardEvent) => {
        console.log(this.input.nativeElement.value);
      });
  }

Don't forget to unsubscribe it on onDestroy.

Upvotes: 0

martin
martin

Reputation: 96899

This is happening because on every key press you create a new chain so debounceTime() has nothing to debounce. Instead make a Subject and push key presses. Then make just one subscription in constructor or in onInit():

keyPress$ = new Subject();

...

keyPress$.pipe(
  debounceTime(150),
  distinctUntilChanged(),
  tap(() => {
    this.paginator.pageIndex = 0;
    this.loadData();
  }),
).subscribe();

...

onKeypressEvent(event: any) {
  this.keyPress$.next(event);
});

Upvotes: 6

Related Questions