Combine Observables
In this part, we'll learn how to combine Observables to create more complex dataflow.
The following examples will group a list Observables, and will re-emit the values they send differently, according to the selected function.
Re-emit all values
The simplest combinator of Observable is merge.
It creates an output Observable which concurrently emits all values from every given input Observable.
As an example, we may create an Observable grouping mouse events:
const onMouseDown$ = fromEventTarget(window, 'mousedown');
const onMouseUp$ = fromEventTarget(window, 'mouseup');
const onMouseDownOrUp$ = merge([
onMouseDown$,
onMouseUp$,
]);
onMouseDownOrUp$((event: MouseEvent) => {
console.log(event.button);
});
// logs the mouse button when down or up
Oftentimes, in real applications, we might not be using this aggregator. Instead, we'll mostly use the following functions.
Emit the values in the form of an Array
Usually, when grouping some Observables, we want to get all the latest values that were emitted in the form of an Array, anytime a change occurs.
This may be done with the function combineLatest.
For example, let's assume we have two Observables containing the firstname and the lastname of a user (ex: coming from two <input> elements), and we want to display the fullname of this user dynamically.
We may write:
// to keep it short in this example, the names are built through 'single'
// but in a real case, they could come from two <input>
const firstName$ = single('Richard');
const lastName$ = single('Stallman');
const onNamesChange$ = combineLatest([
firstName$,
lastName$,
]);
onNamesChange$(([firstName, lastName]) => {
console.log(`${firstName} ${lastName}`);
});
// logs 'Richard Stallman'
In this example, if any of firstName$
or lastName$
changes, then the displayed fullname will change too.
Aggregates the values
Usually, when we group the values with combineLatest
, we want to aggregate the incoming values as one, into a new Observable.
We may think about strings concatenation, performing a sum, etc.
This function is called reactiveFunction.
If we re-write our previous example:
const firstName$ = single('Richard');
const lastName$ = single('Stallman');
const fullName$ = reactiveFunction(
[firstName$, lastName$],
(firstName, lastName) => {
return `${firstName} ${lastName}`;
},
);
fullName$((fullName: string) => {
console.log(fullName);
});
// logs 'Richard Stallman'
It's particularity useful, when we have to transform many values coming from different Observables into one. This is the same behavior as a traditional function, but working with Observables instead.