RXJS operators with use cases
While working on my company project, I have extensively used RXJS in our angular app. At first, I found it a little difficult to understand it but as I worked more on it, I fell in love with it. Thinking of data as a stream at start sounds difficult, but once you understand it, things pretty much move along easily and with the power of RXJS operators, you can do so much in so little code. On top of that, the code is easy to understand.
Great power comes with Great responsibility…
This is applicable to RXJS. While there are a number of operators available in RXJS, one primary responsibility of a developer to unsubscribe from the streams. If this is made as a habit, it will save you from lot of problems, like unexpected output, memory leaks, etc.
Here is the list of operators I am going to talk about in my post.
- distinctUntilChanged
- skip
- take
- filter
- finalize
- tap
distinctUntilChanged: This operator checks every emission of the observable with the previous value and only emits if previous emitted value is not equal to the new emitted value. This works fine for observables emitting strings, numbers, etc. When you have an observable which consists of objects, you can also provide a custom function if you are interested in comparing some specific key-value pairs for the whole object
let obs = [1, 2, 2, 3];
let obsWithObject = [{name: 'test'}, {name: 'test'}, {name: 'test-mak'}];of(obs).pipe(distinctUntilChanged()).subscribe(res => {
console.log(res) // 1, 2, 3
}); of(obsWithObject).pipe(distinctUntilChanged(
(a, b) => (a.name === b.name))).subscribe(res => {
console.log(res) // {name: 'test'}, {name: 'test-mak'}
});
skip: This operator is used to skip a specific number of emissions when the observable starts emitting. A use case is that sometimes, you need to avoid listening the subcription on page first load, but any subsequent emissions need to be listen.
const obs = [1, 2, 3];of(obs).pipe(skip(1)).subscribe(res => {
console.log(res) // 2 , 3
})
take: This operator is the opposite of skip. The number you mention in this operator are the number of emissions to listen to, rest it will unsubscribe. This operator can be useful for auto unsubscribing of observable.
const obs = [1, 2, 3];of(obs).pipe(take(1)).subscribe(res => {
console.log(res) // 1
})
filter: This operator can filter out un-required values of emission. This operator can be used for checking for undefined and null values along with adding any custom filter function if required.
const obs = [1, 2, 3];of(obs).pipe(filter(e => e === 1)).subscribe(res => {
console.log(res) // 1
})
finalize: This operator is used to take any action required after the observable is completed. A good use case if to set the loading status of API call to false once the observable completes.
const obs = [1, 2, 3];
const loading = true;of(obs).pipe(finalize(() => this.loading = false;)).subscribe(res => {
console.log(res) // 1, 2, 3
console.log(this.loading) // false;})
tap: This operator is use to perform some side effects. A simple use case would be to set some values, while the emission are taking place. Also, could be used to add logging for values if required.
const obs = [1, 2, 3];of(obs).pipe(tap(val => console.log(val)))).subscribe(res => {
console.log(res) // 1, 2, 3
})
These are some of the operators which I have used and I have tried to provide use-cases for them. If you find this article useful, do send me some claps.
Please read my next article on higher-order observables.
Keep learning and sharing something new everyday.