DebounceTime & Debounce are the Angular RxJs Operators. Both emit values from the source observable, only after a certain amount of time has elapsed since the last value. Both emit only the latest value and discard any intermediate values. In this tutorial, we will learn how to use both DebounceTime & Debounce with examples.
Table of Contents
Use Case of Debounce Operators
The typeahead/autocomplete fields are one of the most common use cases for Debounce Operators.
As the user types in the typeahead field, we need to listen to it and send an HTTP request to the back end to get a list of possible values. If we send HTTP requests for every keystroke, we make numerous unneeded calls to the server.
By using the Debounce Operators, we wait until the user pauses typing before sending an HTTP Request. This will eliminate unnecessary HTTP requests.
DebounceTime
The Debouncetime emits the last received value from the source observable after a specified amount of time has elapsed without any other value appearing on the source Observable
Syntax
1 2 3 | debounceTime<T>(dueTime: number, scheduler: SchedulerLike = async): MonoTypeOperatorFunction<T> |
Where dueTime
The timeout duration in milliseconds.
How it works
- First, we assign a timeout duration (
dueTime
) to the Debouncetime operator. - The Debouncetime operator starts counting time after it receives a value.
- If the source observable emits a value before the timeout duration, then counting is reset to zero & started again.
- When the timeout duration elapses the operator emits the last value and the counting stops.
- Counting starts again when the operators receive another value.
DebounceTime Example
The following DebounceTime example shows how to use the operator to listen for input field changes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import { Component, VERSION } from "@angular/core"; import { FormControl, FormGroup } from "@angular/forms"; import { Observable, Subscription } from "rxjs"; import { debounceTime } from "rxjs/operators"; @Component({ selector: "my-app", template: ` <form [formGroup]="mform">Name: <input formControlName="name" /></form> `, styleUrls: ["./app.component.css"] }) export class AppComponent { mform: FormGroup = new FormGroup({ name: new FormControl() }); obs:Subscription; ngOnInit() { this.obs=this.mform.valueChanges .pipe(debounceTime(500)) .subscribe(data => console.log(data)); } ngOnDestroy() { this.obs.unsubscribe(); } } |
Optimizing HTTP Request using debounceTime
The following example shows how you can send an HTTP GET Request using the combination of switchMap
, distinctUntilChanged()
& debounceTime
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ngOnInit() { this.obs=this.mform.valueChanges .pipe( debounceTime(500), distinctUntilChanged(), switchMap(id => { console.log(id) return this.http.get(url) }) ) .subscribe(data => console.log(data)); } |
In the above example, debounceTime(500)
waits for the user to stop typing for 500 ms (i.e. half a second). The distinctUntilChanged()
will fire only if the value is changed from the previous value. The switchMap() operator unsubscribes from the previous request and sends the new HTTP request.
Debounce
The Debounce operator is similar to the DebounceTime operator, but another observable will provide the time span. By using the Debounce, we can set the time span dynamically.
Debounce Example
The following example works the same as the previous example. Instead of using the hardcoded time span, we create a new observable using the interval operator.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | import { Component, VERSION } from "@angular/core"; import { FormControl, FormGroup } from "@angular/forms"; import { debounce } from "rxjs/operators"; import { interval, Subscription } from "rxjs"; @Component({ selector: "my-app", template: ` <form [formGroup]="mform">Name: <input formControlName="name" /></form> `, styleUrls: ["./app.component.css"] }) export class AppComponent { mform: FormGroup = new FormGroup({ name: new FormControl() }); obs:Subscription ngOnInit() { this.obs=this.mform.valueChanges .pipe(debounce(() => interval(500))) .subscribe(data => console.log(data)); } ngOnDestroy() { this.obs.unsubscribe() } } |
You can also customize the delay. In the following example, we increase the delay by 100ms after every keystroke.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | delay = 500; obs: Subscription; ngOnInit() { this.obs = this.mform.valueChanges .pipe( debounce(() => { this.delay = this.delay + 100; console.log(this.delay); return interval(this.delay); }) ) .subscribe(data => console.log(data)); } |
Reference
Read More
- Angular Tutorial
- Angular Observable Tutorial
- Create an Observable from a string, array. object, collection
- Observable from events using fromEvent
- Observable pipe
- Map Operator
- Filter Operator
- Tap Operator
- SwitchMap
- MergeMap
- ConcatMap
- ExhaustMap
- take, takeUntil, takeWhile, takeLast
- First, last & Single
- Skip, SkipWhile, SkipUntil & SkipLast
- Scan & Reduce
- DebounceTime & Debounce
- Delay & DelayWhen
- ThrowError
- CatchError
- ReTry & ReTryWhen
- Unsubscribe from an observable
- Subjects in Angular
- ReplaySubject, BehaviorSubject & AsyncSubject
- Angular Subject Example