0%

angular-router-guard

What is Angular Router Guard?

Router Guard is a feature in Angular Router that allows you to run some code before the route is activated. It can be used to protect routes from unauthorized access, redirect users to a login page, or perform any other action before the route is activated.

canActivate

Use case: Only allow authenticated users to access the /product page, otherwise redirect them to the login page.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// app.routes.ts
export const routes: Routes = [
{
path: 'home',
component: HomeComponent,
},
{
path: 'product',
component: ProductComponent,
canActivate: [AuthGuard],
},
{
path: 'login',
component: LoginComponent,
}
];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// auth-guard.service.ts
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {
}

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): MaybeAsync<GuardResult> {
if (this.authService.isAuthenticated()) {
return true;
} else {
this.router.navigate(['login']);
return false;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
@Injectable({
providedIn: 'root'
})
export class AuthService {
constructor() { }

isAuthenticated() {
// Put authentication logic here
return false;
}
}

canActivateChild

Similar to canActivate, but it is used to protect child routes.
In the following example, only authenticated users can access the child routes of the /product page.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// app.routes.ts
export const routes: Routes = [
{
path: 'home',
component: HomeComponent,
},
{
path: 'product',
component: ProductComponent,
children: [
{ path: 'detail', component: ProductDetailComponent },
{ path: 'edit', component: ProductEditComponent },
],
canActivateChild: [AuthGuard],
},
{
path: 'login',
component: LoginComponent,
}
];

canDeactivate

Use case: Confirm with the user before leaving the page. For example, make sure the user wants to leave the page without saving changes.

1
2
3
4
5
6
7
8
9
10
11
12
// app.routes.ts
export const routes: Routes = [
{
path: 'home',
component: HomeComponent,
},
{
path: 'post',
component: PostComponent,
canDeactivate: [SaveGuard],
},
];
1
2
3
4
5
6
7
8
9
10
11
12
13
// save-guard.service.ts
export class SaveGuard implements CanDeactivate<any> {
constructor(private saveService: SaveService) {
}

canDeactivate(component: any, currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot, nextState: RouterStateSnapshot): MaybeAsync<GuardResult> {
if (this.saveService.hasSavedData()) {
return true;
} else {
return confirm('You have unsaved changes. Do you really want to leave?');
}
}
}
1
2
3
4
5
6
7
8
9
// save.service.ts
export class SaveService {
constructor() { }

hasSavedData() {
// Put logic to check if data is saved
return false;
}
}

canLoad

Use case: Guard when calling loadChildren in the route configuration. Note that canLoad not works for loadComponent.

1
2
3
4
5
6
7
const routes: Routes = [
{
path: 'premium',
canLoad: [PremiumFeatureGuard], // Apply PremiumFeatureGuard to prevent lazy loading
loadChildren: () => import('./premium-feature.module').then(m => m.PremiumFeatureModule)
},
];

Note that canLoad is deprecated, use canMatch instead.

canMatch

Use case: Guard when matching the route. If the guard returns false, the route will not be matched.

1
2
3
4
5
6
// app.routes.ts
{
path: 'product',
loadComponent: () => import('./product/product.component').then(m => m.ProductComponent),
canMatch: [CanMatchGuard],
},
1
2
3
4
5
6
7
8
9
// can-match.guard.ts
export class CanMatchGuard implements CanMatch {
constructor() {
}

canMatch(route: Route, segments: UrlSegment[]): MaybeAsync<GuardResult> {
return false;
}
}