Say I want to subscribe to 3 observables A B and C, where some effect depends on the results of A and B, and some effect depends on the results of A B and C. The way I know how to do this is:
forkJoin({
aAndB: forkJoin({
a: of('a'),
b: of('b')
}).pipe(
tap(aAndB => {
//do something with aAndB.a and aAndB.b
})
),
c: of('c')
}).subscribe(allthree => {
console.log(allthree);
});
Current output:
{
aAndB: {
a: 'a',
b: 'b'
},
c: 'c'
}
But my desired output is to have aAndB spread/flattened like this:
{
a: 'a',
b: 'b',
c: 'c'
}
Any way to achieve this?
I would use combineLatest
to create independent observables for each set of values you care about. You can use the same sources in each declaration:
a$ = of('a');
b$ = of('b');
c$ = of('c');
ab$ = combineLatest({ a: a$, b: b$ });
abc$ = combineLatest({ a: a$, b: b$, c: c$ });
ab$.subscribe(({a, b}) => {
// side effect AB
});
abc$.subscribe(({a, b, c}) => {
// side effect ABC
});
Since ab$
and abc$
both use a$
and b$
you may want both subscribers to share a single subscription (in case these observables were doing some kind of work you don't want repeated, like making a network call).
You can accomplish this by using shareReplay
:
a$ = of('a').pipe(shareReplay(1));
b$ = of('b').pipe(shareReplay(1));