Combination Operators
startWith
Emits this value first, before the values emitted by the observable.
import { startWith } from "rxjs/operators";
const numbers$ = of(1,2,3);
numbers$.pipe(
startWith('a', 'b', 'c')
)
.subscribe(console.log)
a
b
c
1
2
3
<div>
<h2 id="countdown"></h2>
<div id="message"></div>
<button id="abort">Abort Mission</button>
</div>
// element refs
const countdown = document.getElementById('countdown');
const message = document.getElementById('message');
const abortButton = document.getElementById('abort');
// streams
const counter$ = interval(1000);
const abortClick$ = fromEvent(abortButton, 'click');
const COUNTDOWN_FROM = 10;
counter$.pipe(
mapTo(-1),
scan((accumulator, current) => {
return accumulator + current;
}, COUNTDOWN_FROM),
takeWhile(value => value >= 0),
takeUntil(abortClick$),
startWith(COUNTDOWN_FROM)
)
.subscribe(value => {
countdown.innerHTML = value;
if (!value) {
message.innerHTML = 'Liftoff!'
}
})
endWith
Emits this value last, after the values emitted by the observable.
import { endWith } from "rxjs/operators";
const numbers$ = of(1,2,3);
numbers$.pipe(
endsWith('x', 'y', 'z')
)
.subscribe(console.log)
1
2
3
x
y
z
concat
Concat allows you to create an observable from multiple other observables. On subscription, the concat will subscribe to the observables in order.
import {concat, interval} from "rxjs";
const interval$ = interval(1000)
concat(
interval$.pipe(take(3)),
interval$.pipe(take(2))
).subscribe(console.log)
0
1
2
0
1
merge
Lets you subscribe to multiple observables and emits values as they occur. Creates an observable by merging together other observables. Merge should be used when the observables relate to each other and have a common solution.
import {merge} from "rxjs";
const keyup$ = fromEvent(document, 'keyup');
const click$ = fromEvent(document, 'click');
merge(
keyup$,
click$
).subscribe(console.log)
// element refs
const countdown = document.getElementById('countdown');
const message = document.getElementById('message');
const pauseButton = document.getElementById('abort');
const startButton = document.getElementById('start');
// streams
const counter$ = interval(1000);
const pauseClick$ = fromEvent(pauseButton, 'click');
const startClick$ = fromEvent(startButton, 'click');
const COUNTDOWN_FROM = 10;
merge(
startClick$.pipe(mapTo(true)),
pauseClick$.pipe(mapTo(false))
).pipe(
// switchmap to counter
switchMap(shouldStart => shouldStart ? counter$ : of(null)),
mapTo(-1),
scan((accumulator, current) => {
return accumulator + current;
}, COUNTDOWN_FROM),
takeWhile(value => value >= 0),
startWith(COUNTDOWN_FROM)
)
.subscribe(value => {
countdown.innerHTML = value;
if (!value) {
message.innerHTML = 'Liftoff!'
}
})
combineLatest
CombineLatest creates an observable from a number of other variables. On subscription, it subscribes to all inner observables, after all observables have emitted at least one value it will emit the last value emitted from each observable as an array each time any of the observables emits a value.
import {combineLatest} from "rxjs";
const keyup$ = fromEvent(document, 'keyup');
const click$ = fromEvent(document, 'click');
combineLatest(
[keyup$,
click$]
).subscribe(console.log)
combineLatest(
[keyupAsValue(first),
keyupAsValue(second)]
).pipe(
filter(([first, second]) => {
return !isNaN(first) && !isNaN(second)
}),
map(([first, second]) => first + second)
)
.subscribe(console.log)
withLatestFrom
withLatestFrom is similar to combineLatest, but it is a pipeable operator that takes in a secondary stream. The value will only be emitted if both subscriptions have a value when the first is activated. It will not occur when only the second one is activated.
click$.pipe(
withLatestFrom(interval(1000))
).subscribe(console.log)
forkJoin
forkJoin takes in a number of observables and once all observables have completed it emits the last value emitted from each of them.
const numbers$ = of(1,2,3);
const letters$ = of('a', 'b', 'c');
forkJoin(
[ numbers$, letters$]
).subscribe(console.log)
[3, 'c']
If you'd rather output an object than an array you can do the following.
const numbers$ = of(1,2,3);
const letters$ = of('a', 'b', 'c');
forkJoin(
{ numbers: numbers$, letters: letters$ }
).subscribe(console.log)
{
letters: "c";
numbers: 3;
}