Angular + debounceTime
January 25, 2024
debounceTime
is a RxJS operator that emits latest value from the source Observable
after a given time span has passed without another source emission. It behaves same as RxJS delay
but emits only the latest value. debounceTime
delays the values emitted by source Observable
for the given due time and within this time if a new value arrives, the previous pending value is dropped. In this way debounceTime
keeps track of most recent value and emits that most recent value when the given due time is passed. debounceTime
is an RxJS operator declared as following.
debounceTime(dueTime: number, scheduler: Scheduler): Observable
debounceTime
is imported as following.
import { debounceTime } from 'rxjs/operators';
pipe
operator of Observable
. debounceTime
is useful in operation where user changes inputs frequently such as search operation.
1. Understanding debounceTime
Suppose we have a simple form with an input field to take input from user to search a book.<form [formGroup]="bookForm"> ID: <input formControlName="bookId"> </form>
this.bookId.valueChanges.pipe( tap(val => console.log(val)) ).subscribe(data => this.userInput = data);
valueChanges
that returns Observable
instance.
If we want to process latest user input with a certain time gap from the time the last user input processing has taken place, and not for every user input change, then we can use RxJS
debounceTime
as following.
this.bookId.valueChanges.pipe( debounceTime(2000), tap(val => console.log(val)) ).subscribe(data => this.userInput = data);
tap
will get latest user input only after 2 seconds from time the previous user input has processed. This is because debounceTime
will not emit value for the given due time. Once debounceTime
has emitted value then next value will be emitted only after 2 seconds with latest value in the case user is continuously entering data into input box.
2. Using debounceTime with switchMap
Suppose we want to search book for the keyword entered by user. It is possible that user may change keyword frequently and in that case every time search operation will be performed. This operation may be costly because it may involve HTTP hit, database hit etc. Suppose we want search operation on change input value and user wants to search for book id. To avoid frequent hit, we may usedebounceTime
as following.
this.bookId.valueChanges.pipe( debounceTime(1000), switchMap(id => { console.log(id); return this.bookService.getBook(id); }) ).subscribe(res => this.book = res);
3. Using debounceTime with fromEvent
fromEvent
creates an Observable
instance that emits events of given type coming from the given event target. In our example we have a <div> element. We will catch mouse over event.
fromEvent(document.getElementById('myelement'), 'mouseover').pipe( debounceTime(1000), map(data => data.srcElement) ).subscribe(val => console.log(val));
<div id="myelement"> Mouse over </div>
fromEvent
code executes. It is possible that we may perform mouse over operation multiple times in a very short span of time and hence complete process will execute for that number of times. To avoid unnecessary execution, we can use debounceTime
. In above code we have used debounceTime
with 1 second due time. For two consecutive mouse over operation, only after 1 second the code will execute if the code has executed already.