2

first i have created 2 guards one check if user signin if not navigated hie to login route

this is code

 import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { Observable } from 'rxjs'; import { AuthenticationService } from '../auth/authentication.service'; import { Router } from '@angular/router'; import { tap, map, take } from 'rxjs/operators'; import {of} from 'rxjs'; @Injectable({ providedIn: 'root' }) export class IsUserGuard implements CanActivate { constructor( private auth:AuthenticationService, private router:Router){} canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { return this.auth.user$.pipe( take(1), map(user => !!user), tap(isAuthenticated => { if(!isAuthenticated){ console.log('must login'); this.router.navigate(['/login']); } }) ) } } 

so , it's working great but the issue here in the second guard i check if user signin he don't allowed to browse login route again so i create this guard

import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { Observable } from 'rxjs'; import { Router } from '@angular/router'; import { AuthenticationService } from '../auth/authentication.service'; import { tap, take, map, } from 'rxjs/operators'; import { of } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class IsGuestGuard implements CanActivate { constructor(private router:Router, private auth:AuthenticationService){} canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { return this.auth.user$.pipe( take(1), map(user => !!user), tap(isAuthenticated => { if(isAuthenticated){ console.log('not a allow') this.router.navigate(['']); } else{ console.log('allowe to show') return true //return of(true) give me the same resault } }), ) } } 

it's working and console printed 'allowe to show' but the page doesn't appear so i feel i'm in loop don't stop , if I return true instead my code in second guard the page working

this is a routes code also

 const routes: Routes = [ { path: '', component: PagesComponent, canActivate:[IsUserGuard], children: [ { path: '', loadChildren: './components/dashboard/dashboard.module#DashboardModule' }, ] }, { path: 'login', canActivate: [IsGuestGuard], loadChildren: './auth/auth.module#AuthModule', }, { path: '404', component: ErrorPageComponent }, { path: 'error/:type', component: ErrorPageComponent }, ]; 

this code is working after help guys @JeffFairley @fan-cheung , thanks guys

export class IsGuestGuard implements CanActivate { constructor(private router:Router, private auth:AuthenticationService){} canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { return this.auth.user$.pipe( map(isAuthenticated => { if(isAuthenticated){ this.router.navigate(['/']); return false } return true }) ) } } 
7
  • You are printing the same message in both cases. Change the log message in if and else condition and check again which criteria is passed. Commented Oct 10, 2018 at 21:02
  • @SunilSingh sorry i copy wrong code, i cheek it again and still the same Commented Oct 10, 2018 at 21:29
  • Are you using both of the Guards for the same routing ? If yes then both of these guards will be in forever loop. To check this better to put the console log at the beginning. Commented Oct 10, 2018 at 21:41
  • 1
    Your example has return true inside a tap(). You cannot return from a tap as it does not transform the data. If you intend to transform the data, you should use map(). Fan Cheung answered the same. Commented Oct 11, 2018 at 7:17
  • 1
    @JeffFairley it's working great, so the first guard also i shouldn't use tap just the map to handle what i want to do and return the value as boolean Commented Oct 11, 2018 at 12:58

1 Answer 1

5

The boolean is already returned by map(user=>!!user), tap is a side effect operator. Try replace tap with map() and return correct value see if it's working.

 canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { return this.auth.user$.pipe( take(1), map(user => !!user), map(isAuthenticated => { if(isAuthenticated){ console.log('not a allow') this.router.navigate(['']); return false } console.log('allowe to show') return true //return of(true) give me the same resault }), ) } 
Sign up to request clarification or add additional context in comments.

1 Comment

it's working great, so the tab in guard it's not useful in my code ! i just use one map not two and working , and inside map handle the data and run what i want and return boolean value in the end

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.