How to spread a nested observable

157 Views Asked by At

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?

1

There are 1 best solutions below

1
On BEST ANSWER

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));