Noel Delgado
Noel Delgado

Reputation: 183

CanActivate: Converting Observable<Observable<boolean>> to Observable<boolean>

I have a user settings page that only the owner should have access to. I want to use CanActivate to implement the restriction. CanActivate requires the output to be boolean or the observable of a boolean. However, my code outputs an observable of an observable of a boolean.

Type 'Observable<Observable<boolean>>' is not assignable to type 'boolean | Observable<boolean> | Promise<boolean>'.

Here my code

@Injectable()
export class UserGuard implements CanActivate {

  constructor(
    private route: ActivatedRoute,
    private userService: UserService
  ) { }

  canActivate() {
    const username = this.route.snapshot.paramMap.get('username');

    return this.userService.authState().map(auth => {
      return this.userService.getByUid(auth.uid).map(user => {
        return user.username === username ? true : false;
      });
    });
  }
}

Upvotes: 1

Views: 903

Answers (1)

Explosion Pills
Explosion Pills

Reputation: 191749

Use .switchMap in order to flatten the observable. Read about it more here: https://www.learnrxjs.io/operators/transformation/switchmap.html

Essentially if you chain .switchMap to a source observable and an inner observable is returned, that observable will be subscribed to and its value emitted rather than the observable itself being emitted:

return this.userService.authState().switchMap(auth => {

In this case you can also flatten your code slightly by chaining .map to the original observable stream.

return this.userService.authState().switchMap(auth =>
  this.userService.getByUid(auth.uid)
).map(user => user.username === username);

Upvotes: 3

Related Questions