Router Guards In Angular (canActivate, canActivateChild, canDeactivate, canLoad, resolve)

Bittu Kumar
4 min readOct 5, 2023

Route guard is a feature that allows you to control and protect the navigation to certain routes in your application based on condition provided.

Some common application of the route guard is:

  • Allow access to certain parts of the application to specific users
  • Form Confirmation: to confirm the navigation
  • Fetching some data before you display the component.

There is 5 types of router guard:

  • canActivate
  • CanDeactivate
  • CanActivateChild
  • CanLoad
  • resolve

4 Easy steps to create and use router guards:

  1. generate a guard (ng generate guard my-guard)
  2. Implement Guard Logic in generated guards (canActivate, canDeactivate …..)
  3. register guard in root module providers
  4. Apply the guards to routes in app-routing.module.ts

This is how my app routing file looks like and different guards example:

const routes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{
path: 'products',
component: ProductsComponent,
resolve: { data: ResolveGuard },
},
{
path: 'about',
component: AboutComponent,
canActivateChild: [RoleGuard],
children: [{ path: 'edit', component: EditAboutComponent }],
},
{
path: 'contact',
component: ContactComponent,
canDeactivate: [NotCompleteGuard]
},
{
path: 'offers',
canLoad: [ModuleGuard],
loadChildren: () =>
import('./components/offers/offers.module').then((m) => m.OffersModule),
},
{ path: 'admin', component: AdminComponent, canActivate: [AuthGuard] },
{ path: 'access-denied', component: AccessDeniedComponent },
{ path: '**', component: NotFoundComponent },
]

Now we will understand all route guards one by one.

canActivate:

CanActivate is a route guard in Angular that allows or prevents navigation to a route based on certain conditions.

It is used to control access to a route before the route is activated, making it useful for implementing authentication and authorization checks or validating route parameters.

export class AuthGuard implements CanActivate {
userRole = 'user';

constructor(private router: Router) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
if (this.userRole != 'admin') {
this.router.navigate(['access-denied']);
}
return true;
}
}

canDeactivate:

The CanDeactivate route guard in Angular allows you to determine if a user can leave the current route and navigate away from it. It's commonly used to prompt for confirmation or perform checks, ensuring that the user doesn't accidentally lose unsaved data or take unintended actions when leaving a page.

export class NotCompleteGuard implements CanDeactivate<unknown> {
canDeactivate(
component: unknown,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState?: RouterStateSnapshot
):
| Observable<boolean | UrlTree>
| Promise<boolean | UrlTree>
| boolean
| UrlTree {
let response = confirm('Are you sure you want to leave!');
if (response == true) {
return true;
} else {
return false;
}
}
}

canActivateChild:

The CanActivateChild route guard in Angular is used to control whether a user can access the child routes of a route that has child routes.

It is similar to canActivate. This guard is also used to control route access by applying checks and logic before allowing navigation.

  • CanActivate is used to control access to a specific route before it is activated.
  • CanActivateChild is used to control access to child routes when a route has nested or child routes. It applies checks specifically to the child routes of a route.
export class RoleGuard implements CanActivateChild {
userRole = 'adminn';
canActivateChild(
childRoute: ActivatedRouteSnapshot,
state: RouterStateSnapshot
):
| Observable<boolean | UrlTree>
| Promise<boolean | UrlTree>
| boolean
| UrlTree {
if (this.userRole !== 'admin') {
alert("You don't have access");
return false;
}
return true;
}
}

canLoad:

The CanLoad route guard in Angular is used to prevent the loading of lazy-loaded modules until certain conditions are met.

CanLoad is similar to canActivate but the difference is canActivate works on individual component but canLoad decides whether to load entire module or not.

export class ModuleGuard implements CanLoad {
userRole = 'admin';
constructor(private router: Router) {}
canLoad(
route: Route,
segments: UrlSegment[]
):
| Observable<boolean | UrlTree>
| Promise<boolean | UrlTree>
| boolean
| UrlTree {
if (this.userRole !== 'admin') {
this.router.navigate(['access-denied']);
}
return true;
}
}

resolve:

The Resolve route guard in Angular is used to fetch data or perform asynchronous operations before a route is activated.

It waits until the required data is available even if it is taking much time.

In my example I have given 3 seconds delay manually in response time. So after 3 seconds only routes get loaded. It can help us to resolve data dependencies.

export class ResolveGuard implements Resolve<string> {
userRole = 'user';
constructor(private dataService: DataService) {}
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<string> | Promise<string> | string {
return this.dataService.getData();
}
}

I have created one example project for better understanding and uploaded in GitHub.

You can explore demo here below link:

Github link: https://github.com/bittu1040/angular-router-guard-demo

You can start exploring by cloning this repository.

You can find me here, Just send me Hi. I would be happy to talk.

https://www.linkedin.com/in/bittukumar-web/

Happy learning.
Thanks for reading!!

--

--