Avoiding nested subscriptions depends on the nature of the observables and how they depend on each other:
Co-dependent observables
When an observable (this.grants.get()
) depends on the notification from another observable (this.user
), you could use any of the RxJS higher order mapping operators switchMap
, mergeMap
, concatMap
and exhaustMap
. Each has their own purpose. You could find the differences between them here.
Brief differences b/n them
switchMap
– cancel inner observable if the outer observable emitsmergeMap
– trigger inner observable for each outer notification (flatten the outer notifications)concatMap
– essentiallymergeMap
with single concurrent request at any time (flattens the outer notifications but emit them in order)exhaustMap
– ignore outer notifications if inner observable hasn’t completed
Illustration using switchMap
operator
this.user.pipe(
switchMap(e => this.grants.get(e))
).subscribe((x) => {
console.log(x)
});
Independent observables
If the observables are independent of each other, you could use RxJS functions like forkJoin
, combineLatest
or zip
to trigger the observables in parallel.
Brief differences b/n them
forkJoin
α – emit only when all the observables completecombineLatest
α,β – emit when any of the observables emit (observables w/o emissions will emit old value)zip
α,β – emit when all of the observables emit
Illustration using forkJoin
forkJoin(this.obs1, this.obs2, ...).subscribe(
res => console.log(res)
);
α – emits an array of notifications from each observable (eg. (this.obs1, this.obs2, ...)
will emit ['res from obs1', 'res from obs2', ...]
).
β – all observables should emit atleast once for the operator to emit