RxJS Composing functions and operators - zip, combineLatest, withLatestFrom for Component State Switching (2024)
RxJS Tutorial - Table of Contents
Overview
In this article, we will learn new functions and operator that allows to combine a few observable sequences in a different ways. We will review Zip and combineLatest functions and withLatestFrom operator.
Composing functions and operators usually accept observables as their params and also they return observable that emits array with values produced by argument observables.
This result observable emission logic is different depending on which operator or function we use, let's start reviewing them one by one.
RxJS Zip function:
Zip Combines mulitple Observables emitted values with same index. Return array of respective values.
As can be seen in the diagram, So we've had two observable sequences to zip function and want to receive array of values, only after both observables produce values. So the output Observable value would be : [[[0, 10], [1, 11]]
zip (observable1, [ observable2, observable3,..., resultSelector]);
- Zip waits until all the params observables emit values with same index number and only then emits array of these values.
- Zip accepts one or more observables as a params and you can also provide last param as function it is treated as a resultSelector
- resultSelector : You can use result selector for additional emitted data manipulation.
import { zip, of } from 'rxjs';
import { map } from 'rxjs/operators';
let age$ = of<number>(27, 25, 29);
let name$ = of<string>('Foo', 'Bar', 'Beer');
let isDev$ = of<boolean>(true, true, false);
zip(age$, name$, isDev$).pipe(
map(([age, name, isDev]) => ({ age, name, isDev })),
)
.subscribe(x => console.log(x));
// outputs
// { age: 27, name: 'Foo', isDev: true }
// { age: 25, name: 'Bar', isDev: true }
// { age: 29, name: 'Beer', isDev: false }
We have three observable sequences here, ages name and isdev. Each of them will emit three values one by one, we feed them to zip function and subscribe to result observable.
As you can see, each time of the argument observables emit values with same index result observable produces array of these values.
We can use zip function in our web application at time of bootstrap of application or component, where we are waiting for more than one http data to render the component. So zip function can help in better state management.
RxJS combineLatest function
CombineLatest combines multiple observables to create an observable, those values are calculated from the latest values of each of its input observables, once any of them emit irrespective of their index.
Please note that combineLatest result observable only starts producing values only if all arguments observable has at least one value already emitted, and it doesn't wait for all argument observables to have same index value emitted
Let's take a look at this diagram :As you can see, if all argument observables has at least one value emitted, combined latest result observable produces array of emitted values ([0,10]). And each time any of param observable sends new data result observable will meet new array of values as well. ([1,10],[1,11])
Let's see simple example
import { combineLatest, of } from 'rxjs';
import { map } from 'rxjs/operators';
const amount = of(70, 72, 76, 79, 75);
const conversionRate = of(0.06, 0.07, 0.08);
const fees = combineLatest(amount, fees).pipe(
map(([a, r]) => (a * r)),
);
fees.subscribe(x => console.log('commission is ' + x));
RxJS withLatestFrom Operator
withlatestFrom combine the source observable with other observables to create a result observable. Those values are calculated from the latest values of each, only when source emits so source emission is the trigger.
Next we will see RxJS Higher-Order Observable Mapping