I have HTTP interceptor. In that interceptor, before I change the request, I need a loader to turn be turned on.
What really worries me is that I end up having lots of switchMap
s.
why?
What I do in my loader service
public showLoader(message) {
return this.translateService.get(message).pipe(
switchMap((translatedMessage) => {
this.loader$ = from(
this.loadingController.create({ message: translatedMessage })
);
return this.loader$.pipe(
switchMap((loader) => {
return from(loader.present());
})
);
})
);
}
in my interceptor
public intercept(request: HttpRequest<any>, next: HttpHandler) {
return this.loaderService.showLoader("WAITING").pipe(
take(1),
switchMap( ()=>{
so there are already 3 nested switchMap
s. And below it, I need 2 or 3 more switchMap
s (one for getting tokens from storage and one for something else). Basically end up having 5 switchMap
s.
Question: Is nesting all these switchMap
s considered an anti-pattern?
Use mergeMap if you simply want to flatten the data into one Observable, use switchMap if you need to flatten the data into one Observable but only need the latest value and use concatMap if you need to flatten the data into one Observable and the order is important to you.
Why use switchMap ? The main difference between switchMap and other flattening operators is the cancelling effect. On each emission the previous inner observable (the result of the function you supplied) is cancelled and the new observable is subscribed. You can remember this by the phrase switch to a new observable.
The switchMap operator maps each value to an observable, then it flattens all of the inner observables. It basically projects each source value to an observable which is then merged in the output observable, emitting values only from the most recently projected observable.
switchMap operator is basically a combination of two operators - switchAll and map. The map part lets you map a value from a higher-order source observable to an inner observable stream.
It's fine to use many switchMap
especially when you need asynchronous behaviour, the bad practice is to touch things outside of the data stream.
In your code this.loader$
is an example of it, instead of using variables outside of a stream try to build a pipe that does everything you want inside of itself.
You can even omit from
if this.loadingController.create
and loader.present
are Promise
like, switchMap
supports Observable
, Promise
, Array
and Iterator
.
Your code could be like that
public showLoader(message) {
return this.translateService.get(message).pipe(
switchMap(translatedMessage => this.loadingController.create({message: translatedMessage})),
switchMap(loader => loader.present()),
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With