CanActivate and CanLoad are both route guards in Angular that are used to improve the user experience. CanActivate protects the route but doesn't prevent the module from loading. CanLoad protects the route completely, including all routes associated with the module.
CanActivate Guard
Purpose:
- Route Activation:
CanActivate
is used to determine if a route can be activated. It checks permissions before navigating to a route.
Use Case:
- Used to prevent access to a route based on user authentication, roles, or other conditions.
- Ideal for protecting both eagerly and lazily loaded routes.
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if (this.authService.isLoggedIn()) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
}
const routes: Routes = [
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] }
];
Behavior:
- The guard runs each time the route is accessed.
- It only checks if the route can be activated, not if the module can be loaded.
CanLoad Guard
Purpose:
- Module Loading:
CanLoad
is used to determine if a module can be loaded. It prevents the module from being loaded if the conditions are not met.
Use Case:
- Used specifically for lazy-loaded routes to prevent the entire module from loading if the user is not authorized.
- Ideal for optimizing performance by avoiding the loading of unnecessary modules.
import { Injectable } from '@angular/core';
import { CanLoad, Route, UrlSegment, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
@Injectable({
providedIn: 'root'
})
export class CanLoadGuard implements CanLoad {
constructor(private authService: AuthService, private router: Router) {}
canLoad(
route: Route,
segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean {
if (this.authService.isLoggedIn()) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
}
const routes: Routes = [
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule),
canLoad: [CanLoadGuard]
}
];
Behavior:
- The guard runs only once when the module is about to be loaded.
- Prevents the lazy-loaded module from being downloaded if the guard fails.
Comparison Summary
Feature | CanActivate | CanLoad |
---|---|---|
Purpose | Controls route activation | Controls module loading |
Use Case | Protects both eagerly and lazily loaded routes | Specifically for lazy-loaded modules |
Execution | Runs every time the route is accessed | Runs only once when the module is about to be loaded |
Impact | Checks permissions before activating the route | Prevents the module from being loaded if the user is unauthorized |
Implementation | canActivate: [AuthGuard] | canLoad: [CanLoadGuard] |
Choosing Between CanActivate and CanLoad
- Use
CanActivate
when you want to check permissions every time a route is accessed, ensuring that even if the module is already loaded, access is restricted based on the current state. - Use
CanLoad
when you want to prevent the application from even downloading and loading the module if the user does not meet certain criteria, optimizing performance by avoiding unnecessary module loads.
CanActivateChild:
This guard is used to check if a user is allowed to navigate to a child route. It is similar to the CanActivate guard, but it is called before the child route is activated.CanDeactivate:
This guard is used to check if a user is allowed to leave a route. It is called before the user leaves the route.CanLoad:
This guard is used to check if a module can be loaded lazily. It is called before the module is loaded.
Resolve:
This guard is used to resolve data before a route is activated. It is called before the CanActivate guard.
Tags
Angular