I have this method to get token via localstorage, if token is not exist or is expired, I will call API to get another token and store to localstorage.
In this case, which map should I use, currently using mergeMap, or other way to do this?
public doGetToken():Observable<Token> {
return this.loadToken().pipe( //get via localstorage
map(token=>{
let valid = this.validateTokenIsValid(token);
let data = {
token: token,
valid: valid
};
return data;
}),
mergeMap(data=>{
if (!data.valid) {
return this.doApiGetToken(data.token).pipe(
map(
token=>{
this.saveToken(token); //save to localstorage
return token;
}
)
);
} else {
return of(data.token);
}
})
);
version: Angular 5, rxjs5
Thank you in advance.
If you only make one request, then it doesn't matter which map you use.
mergeMap (also called flatMap), concatMap , exhaustMap or switchMap will behave the same.
These operators behave differently when you emit more than 1 value:
switchMap
will apply the mapping to the latest input received:
Src : -----A----B----C--D-E-------
switchMap (x => x--x) // emit x twice when received
Out: ------A--A-B--B-C-D-E--E----
concatMap
will finish the mapping before taking another input:
Src : -----A----B----C--D-E-----------
concatMap (x => x--x) // emit x twice when received
Out: ------A--A-B--B-C--C--D--D-E--E
mergeMap
is like concatMap, but it doesn't wait for mapping to complete. The results can overlap though:
Src : -----A----B----C-D---E-----------
mergeMap (x => x--x) // emit x twice when received
Out: ------A--A-B--B-C-D-C-D-E--E-----
exhaustMap
is like a reversed switchMap, it gives priority to the output:
Src : -----A--------B----C-D---E-----------
exhaustMap (x => x--x--x) // emit x thrice when received
Out: ------A--A--A--B--B--B-D--D--D-------
For more information :
https://medium.com/@vdsabev/the-simple-difference-between-rxjs-switchmap-and-mergemap-397c311552a5
Marble diagrams :
http://rxmarbles.com/#mergeMap
Edit : I moved the simplification of your code to the bottom to make the general information visible at first sight.
public doGetToken(): Observable<Token> {
return this.loadToken()
.pipe( //get via localstorage
mergeMap(token => {
if(!this.validateTokenIsValid(token))
return of(token)
return this.doApiGetToken(token)
.pipe(
tap( token => this.saveToken(token)) //save to localstorage
);
})
)
};
single source observables the above operators does not differ.
switchMap: emits values and is only interested in the very last one it sent. All the responses of the calls before get ignored.
concatMap: behaves like a queue: It stores all calls and sends one after another. If one is completed, the next one is being processed.
mergeMap: Also sends all requests, like concatMap but does not wait until the response is coming back. It sends them out as they come. But it receives every response and does not ignore something. The order here is not guaranteed.
exhaustMap: Emits the first request and ignores all future requests until the first one gets back. Then it is ready for a new one.
Please refer this link. really great one
https://offering.solutions/blog/articles/2021/03/08/switchmap-mergemap-concatmap-exhaustmap-explained/
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