15

I have text box and assigned to it keyup event a search function but I want it to happen with delay, not on every keypress

here is the html code :

<input type="text" [(ngModel)]="searchedKPI" (keyup)="searchConfigTree()">

and here is ts code :

list = list.filter(item => item.label.toLocaleLowerCase().includes(this.searchedKPI.toLocaleLowerCase())).slice();

and here is the example I wanted to search "text" string but the event happens 4 times, I want to this happens once only for "text" string :

enter image description here

what the solution?

Roham Rafii
  • 2,929
  • 7
  • 35
  • 49
Vala Khosravi
  • 2,352
  • 3
  • 22
  • 49

4 Answers4

18

Welcome to the Observable's world. Just use Observable to get the desired result. Get the reference of your input in the component and use this code. debounceTime will let the event to trigger at least after 1 second from the previous trigger. It will let you not to fire on every keyup when user types fast.

Observable.fromEvent(yourInput, 'keyup').debounceTime(1000).subscribe(value => /* */)

In the subscribe method you can write your logic. The value is the value of the input.

Suren Srapyan
  • 66,568
  • 14
  • 114
  • 112
11

View template.html

<input type="text" [(ngModel)]="searchedKPI" (keyup)="searchConfigTree()" #something>

component.ts (do not forget implement the AfterViewInit)

     source: any;
     @ViewChild("something") something:ElementRef; 

     ngAfterViewInit(): void {
                this.source = fromEvent(this.something.nativeElement, 'keyup');
                this.source.pipe(debounceTime(1200)).subscribe(c => 
                {
                          list = list.filter(item => item.label.toLocaleLowerCase().includes(this.searchedKPI.toLocaleLowerCase())).slice();
                }
                );
              }
Esteban Perez
  • 390
  • 3
  • 5
  • 4
    what is 'this.source' in this context? – Torsten N. Apr 20 '20 at 09:37
  • @TorstenN. Hello, it's the `Subscription` object output of the `fromEvent(..) function. it can also be used to end the subscription in `ngOnDestroy(..) { }` by calling `this.source.unsubscribe()`whenever we no longer use the actual component to prevent memory leaking issues. – sohaieb azaiez Oct 16 '21 at 09:45
1

This solution works for me

View Template.html

<input type="text" placeholder="Filter..." class="form-control" [(ngModel)]="filter" (input)="searchChange($event.target.value, true)">
<button class="btn btn-primary" type="button" (click)="searchChange(filter, false)"><i class="fa fa-search"></i></button>

Comonent.ts

  filter= '';
  private timer: any;

  searchChange(filter: string, to = false) {
    filter = filter.toLowerCase();

    if (to) {
      clearTimeout(this.timer);

      this.timer = setTimeout(() => {
        this.valuesFilter = this.allValues.filter(f => f.field.toLowerCase().includes(filter));
      }, 400);
    } else {
      this.valuesFilter = this.allValues.filter(f => f.field.toLowerCase().includes(filter));
    }
  }
Stivens
  • 11
  • 1
-1

cant we use timeout function?

(keyup)="keyupFunc()" --> html
keyup() {
       timeout((your function code), delay_time_you_need);
   } --> ts