2

I am trying to build an application using Angular 9 and in my

app-routing.module.ts

  const routes: Routes = [
{
    path: '', canActivate:[GuestGuard], component: BlankComponent,  children:[
        {path:'', loadChildren: () => import('./user/user.module').then(m => m.UserModule)}
    ],


},
{
    path: '', canActivate:[AuthGuard], component: UserComponent,  children: [
    {path: 'dashboard', component: DashboardComponent},
    {path:'', children:[
    {path: 'roles',  loadChildren: () => import('./roles/roles.module').then(m => m.RolesModule), },  


}
    ]
},
    { path: '**', redirectTo: '', pathMatch: 'full' },
];

guest-guard.ts

Used to block users who are already logged in

export class GuestGuard implements CanActivate, CanLoad {
    constructor(private auth:Auth, private router:Router){}
    canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
        const userLoggedIn = this.auth.isLoggedIn();
        if(userLoggedIn){
        this.router.navigateByUrl('dashboard');
        return false;
        }
        return true;
    }
    canLoad(
    route: Route,
    segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean {
        const userLoggedIn = this.auth.isLoggedIn();
        if(userLoggedIn){
        this.router.navigateByUrl('dashboard');
        return false;
        }
        return true;
    }
}

auth-guard.ts

Allow access to users logged in (inverse of guest)

export class AuthGuard implements CanActivate, CanLoad {
    constructor(private auth:Auth, private router:Router){}

    canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
        const userLoggedIn = this.auth.isLoggedIn();
        if(!userLoggedIn){
        this.router.navigateByUrl('/');
        return false;
        }
        return true;
    }
    canLoad(
    route: Route,
    segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean {
        const userLoggedIn = this.auth.isLoggedIn();
        if(!userLoggedIn){
        this.router.navigateByUrl('/');
        return false;
        }
        return true;
    }
}

Above code is working fine as expected. But when i use canLoad on the guest path, i get

Throttling navigation to prevent the browser from hanging. See <URL>.

For loggedin user path, the canLoad function is not executed (tested by using console.log)

When should canLoad be used?

Darpan
  • 234
  • 3
  • 15
Alaksandar Jesus Gene
  • 6,523
  • 12
  • 52
  • 83
  • Did you also try this? `{path:'', pathMatch: 'full', loadChildren: () => import('./user/user.module').then(m => m.UserModule)}` – Andrei Gătej May 23 '20 at 08:26

2 Answers2

2

Can Load is used for checking lazy loaded modules whether they should be allowed to login. For eg :-

 {path: 'roles',  loadChildren: () => import('./roles/roles.module').then(m => m.RolesModule), canLoad: [GuesGuard]}, 
Aakash Garg
  • 10,649
  • 2
  • 7
  • 25
1

For non loggedin user AuthGuard should navigate to login page or somewhere available for public access. AuthGuard should guard only internal routes available for logged in users. Also for loogedin users you can have role setting and with CanLoad prevent some lazy modules to be loaded in example admin module could be allowed only for admin role, etc. Inside of Admin module you can with 'canActivate' give access to different features accordingly to some other settings or roles.

You can use guards for other pages too, but you should have some way to distinguish one user from another, in example you can mark anonymous users by saving some mark in local storage so you can see who get first time access etc.

Radik
  • 2,715
  • 1
  • 19
  • 24