Reputation: 12675
If I use the tap rxjs operator on an observable to call another observable, can I guarantee that it completes before the rest of the pipe?
The idea here is to have a service make an http call to the backend, if it's a good login, create a cookie, then return a mapped response to the consuming component. I want to make sure the cookie is added before continuing to make sure there are no race conditions.
import { of, Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators';
const httpObservable = loginAccount('fsdfds', 'fdsfsd');
httpObservable.subscribe(x => {
console.log(x);
});
function loginAccount(username, password): Observable<any> {
const httpResponse = of({ loggedIn: false, data: 'faketokenfrombackend' });
return httpResponse.pipe(
// Will this AWLAYS complete before map?
tap(resp => fakeLocalStorage('Do something with the result')),
// Will this AWLAYS complete before map?
tap(resp => fakeLocalStorage('Do something else with the result')),
map(resp => {
if (!resp.loggedIn)
return { success: false, message: 'really bad thing happened' };
else
return {success: true, message: 'WEEEEEE, it worked!'}
}));
}
function fakeLocalStorage(data: string): Observable<boolean> {
console.log('adding token to cookie');
return of(true);
}
The above script outputs this to the console window as expected, but can I rely on it?
adding token to cookie
adding token to cookie
{success: false, message: "really bad thing happened"}
Upvotes: 2
Views: 6294
Reputation: 43817
Yes, RxJS will run the piped operators in order. As long as the tap operators are synchronous they will complete before the map operator is run. If they do anything asynchronous they will not.
Upvotes: 3