-1

I have two pretty similar guards in angular app. First of them checking is User logged in:

// isUser guard

export class isUser implements CanActivate {
  constructor(
    private fireAuth: AngularFireAuth,
    private router: Router
  ) {}

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
      return this.fireAuth.authState.pipe(
        take(1),
        map(authState => !!authState),
        tap(auth => !auth ? this.router.navigate(['/']) : true)
      )
  }
}

And this one work properly: when user is not logged in it's not allow him to open protected page.

The next guard is almost the same, but it check if user in not logged in:

export class isGuest implements CanActivate {
  constructor(
    private fireAuth: AngularFireAuth,
    private router: Router
  ) {}

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
      return this.fireAuth.authState.pipe(
        take(1),
        map(authState => !!authState),
        tap(auth => auth ? this.router.navigate(['/']) : true)
      )
  }
}

The difference only is: !auth ? this.router.navigate(['/']) vs auth ? this.router.navigate(['/']).

But isUser guard work good, and isGuest always allow page for user. What I did wrong, and why it's can not work?

Volodymyr Humeniuk
  • 3,411
  • 9
  • 35
  • 70

1 Answers1

3

The value emitted by both observables is the same: !!authState, but they shouldn't since one is supposed to emit true only when the user is authenticated, and the other is supposed to emit true only when the user is NOT authenticated.

map() and tap() do different things.

map() tranforms the emitted event into something else.

tap() produces a side effect and leaves the emitted event as is.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Value is not the same, `!!authState` transform returned value to a boolean, because by default it return an object. – Volodymyr Humeniuk Aug 11 '19 at 08:12
  • Maybe the edition to my answer will clear your confusion. – JB Nizet Aug 11 '19 at 08:14
  • 2
    I think @jb-nizet is right. The boolean you return via the ternary expression in your tap is useless as tap does not impact the stream. It might work if you replace tap with map. – johey Aug 11 '19 at 08:15