sami
sami

Reputation: 733

Chain Observables and Promises

I am building an application using Firebase Auth (AngularFire) with Angular 6. I also have a MongoDB service for Role-Base-Access (RBA)

I need to do 3 things in order to resolve whether a user can access a URL path:

  1. Listen to the Firebase authState Observable for the current user
  2. Fetch his latest token ID
  3. Check MongoDB if the user is allowed access to the URL

When all 3 pass, it should return true

I have studied Observables a bit but still feel confused, specially since I am using rxjs 6 and lots of links still refer to before-5.5

This is my canActivate function right now:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) 
{

     return this.authService.user$.pipe(map (user => {

         //user.getIdToken() returns a Promise so I wrap it in an Observable
         return from(user.getIdToken());

     })).pipe(map( tokenValue => {

          //tokenValue is an Observable here 
          this.mongoDBService.validate(tokenValue, state.url);
     }));
}

I was expecting the second "pipe" to listen and receive the result of from(user.getIdToken())

Isn't that how it's supposed to work? If not, can someone please guide me how to chain these 2 observables together?

Thanks

Upvotes: 1

Views: 920

Answers (1)

smnbbrv
smnbbrv

Reputation: 24581

You need to use switchMap (that chains the result observable into the main flow) instead of map (that simply maps emitted value to something else). Also you can use pipe only once:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
  return this.authService.user$.pipe(
    switchMap (user => from(user.getIdToken())),
    switchMap(tokenValue => this.mongoDBService.validate(tokenValue, state.url))
  );
}

I'm not sure what is user.getIdToken() and whether you need from at all. However you main problem should be solved by this.

Upvotes: 1

Related Questions