abidinberkay
abidinberkay

Reputation: 2025

How to add debounce time to in input search box in typescript?

How can i add debounce time to dynamic search box that searches data on table data ? I have looked at some solution on the site but my code is little bit different, I do not use any throttle or something else so I am just confused.

my template code:

<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Search element">

and typescript for that is:

applyFilter(filterValue: string) {
    this.tableDataSource.filter = filterValue.trim().toLowerCase();
}

I want to add debounce time for that the search will be made every 2 seconds and not sending lots of request for every change.

Thanks in advance

I have tried to call the method from another method with pipe

filterData(filterValue: string) {
    this.applyFilter(filterValue).pipe(debounceTime(2000))
}

but now it says, pipe does not exist on type void

Upvotes: 5

Views: 13380

Answers (3)

pas2al
pas2al

Reputation: 594

Template:

<input matInput (input)="terms$.next($event.target.value)" type="text" 
  placeholder="Search element">

Component:

private terms$ = new Subject<string>();

ngOnInit () {
  this.terms$.pipe(
    debounceTime(400), // discard emitted values that take less than the specified time between output
    distinctUntilChanged() // only emit when value has changed
  ).subscribe(term => {
    // do your search with the term
  });
}

Upvotes: 11

Patrik Kelemen
Patrik Kelemen

Reputation: 169

Simply use lodash-decorators and lodash

import { Debounce } from 'lodash-decorators';

class AnyClass {
  constructor() {
    ...
  }

  @Debounce(100)
  filterData(filterValue: string) {
    ...
  }
}

Upvotes: 3

Nithya Rajan
Nithya Rajan

Reputation: 4884

You are using pipe operator against a string. You can only use pipe against an Observable. So, You should create a Subject in your component. Subject in RxJS acts as both an Observable and Observer. In other words, it emits the value as well as listen for that value when the value changes.

private searchSub$ = new Subject<string>();

applyFilter(filterValue: string) {
    this.searchSub$.next(filterValue)
}

ngOnInit() {
   this.searchSub$.pipe(
     debounceTime(400),
     distinctUntilChanged()
   ).subscribe((filterValue: string) => {
     this.tableDataSource.filter = filterValue.trim().toLowerCase();
   });
}

When the applyFilter() method calls on every key press, the Subject emits the filterValue. In your ngOnInit(), you should listen / subscribe to you Subject, so there you can use the pipe operator and debounceTime.

Upvotes: 10

Related Questions