Darthg8r
Darthg8r

Reputation: 12675

Observables inside of tap() complete

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

Answers (1)

Pace
Pace

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

Related Questions