How-to: Simple Angular Debounce using RxJS
Debouncing is the practice of limiting the rate at which a function fires until after some cooling period.
For example, many applications optimize the UX of their search features by presenting items as the user types. This usually involves debouncing the search function in order to avoid unnecessarily calling the server after every keystroke.
This article shows how to effectively debounce Angular functions, using RxJS.
The Pieces
Subject
— a special type of Observable that allows multiple listeners,.next
is used to emit new values,.complete
is used to close subscriptionstakeUntil(Subject)
— used to cancel the search observable if a new value is emitteddebounceTime(milliseconds)
— delays values emitted by the Subject, but drops pending emissions if a new value arrives
Putting It Together
For this example, searchItems
will be the function to debounce
To control the rate at which searchItems
is called, only call the function through an RxJS Subject
with a debounceTime
pipe
For triggering a new search, just call searchNotifier.next()
Finally, cancel any on-going API calls by using a takeUnil
pipe on the search observable.
Optimal Approach using Reactive Forms + switchMap
A couple of optimizations can be made to improve the code
- By grouping the search fields into a
FormGroup
you avoid the need for aSubject
(and lifecycle management) since you already have access to a multi-casting observable with.valueChanges
see https://angular.io/guide/reactive-forms - Use the
async
pipe and reference the search observable directly in the html. By storing the search observable in a variable,switchMap
can be used as an alternative totakeUntil
for cancellation of pending emissions.
switchMap-— On each emission the previous inner observable is cancelled and the new observable is subscribed. You can remember this by the phrase switch to a new observable.