CanActivate vs CanLoad: Which Guard Should You Use in Angular?

In this article, we will discuss two essential routing guards, canActivate and canLoad, which play a crucial role in securing your Angular application. We will mainly focus on these two types of Auth Guards, and find out when, why and how to use them in your Angular application.

During this guide, we will create a sample app to demonstrate how we can use these two guards to provide access protection during Router navigation.

What is canActivate? When to use it?

The canActivate is a routing guard used to determine whether a user can access a specific route. This is particularly useful when implementing access control based on user roles or permissions. canActivate can prevent unauthorized users from accessing certain routes. Which makes the application more secure

.

Using canActivate

To implement canActivate, you need to create a service that implements the CanActivate interface. This interface requires you to define a single method, canActivate, which returns either an Observable<boolean>, Promise<boolean>, or boolean.

 

canActivate Example

Let’s create a sample students app and implement canActivate to restrict access to the “student details” route. First, generate a new service called AuthGuard:

ng generate service auth-guard

 

Next, open the auth-guard.service.ts file and implement the CanActivate interface:

import { Injectable } from '@angular/core';
import {
  CanActivate,
  ActivatedRouteSnapshot,
  RouterStateSnapshot,
} from '@angular/router';

@Injectable({
  providedIn: 'root',
})
export class AuthGuardService implements CanActivate {
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): boolean {
    // Your logic to check user access
    const userHasAccess = false;
    if (!userHasAccess) {
      alert('AuthGuardService - No Access!');
    }
    return userHasAccess;
  }
}

You will see that above, we have an if expression which is checking the userHasAccess boolean. If it’s not positive, canActive will get false as a return and ultimately it will block the route activation in our Routing module. You will see it working going forward.

 

What is canLoad? When to use it?

The canLoad is another routing guard used to determine whether a user can load a specific route. This guard is especially used when loading the lazy-loaded modules. this is useful when you want to prevent unauthorized users from downloading parts in the form of lazily loaded modules of the application, which they are not allowed to access.

 

Using canLoad

To implement canLoad, we can create a service that implements the CanLoad interface. This interface requires to define a single method, canLoad, which returns either an Observable, Promise or boolean.

canLoad Example

Let’s create a sample students app and implement canLoad to restrict access to the lazy-loaded “student details” module. First, generate a new service called LazyLoadGuard:

ng generate service lazy-load-guard

 

Next, open the lazy-load-guard.service.ts file and implement the CanLoad interface:

import { Injectable } from '@angular/core';
import { CanLoad, Route, UrlSegment } from '@angular/router';

@Injectable({
  providedIn: 'root',
})
export class LazyLoadGuardService implements CanLoad {
  canLoad(route: Route, segments: UrlSegment[]): boolean {
    // Your logic to check user access
    const userHasAccess = false;
    if (!userHasAccess) {
      alert('LazyLoadGuardService - No Access!');
    }
    return userHasAccess;
  }
}

 

Creating Students Components

To demonstrate the usage of canActive and canLoad Guards, we will create two components, one will be a simple StudentListComponent and other will be LazyStudentListComponent which will be part of LazyStudentListModule. They can be of any name you want.

Execute the following commands to create these two types of components, one is the simple component and the other will be having its own module:

ng generate component student-list
ng generate module lazy-student-list --route student-list-lazy --module app.module

After creating these components, we will update the Routing module to use our created Auth Guards.

 

Updating the Routing Module to use Guards

Now, head towards the app-routing.module.ts and update it as shown below:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AuthGuardService } from './auth-guard.service';
import { LazyLoadGuardService } from './lazy-load-guard.service';
import { StudentListComponent } from './student-list/student-list.component';

const routes: Routes = [
  {
    path: 'student-list',
    component: StudentListComponent,
    canActivate: [AuthGuardService],
  },
  {
    path: 'student-list-lazy',
    loadChildren: () =>
      import('./lazy-student-list/lazy-student-list.module').then(
        (m) => m.LazyStudentListModule
      ),
    canLoad: [LazyLoadGuardService],
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

You will notice that for StudentListComponent, we have added the canActivate param with assigned auth class named AuthGuardService.

For the lazily loaded module named LazyStudentListModule we have added the canLoad param with LazyLoadGuardService. The canLoad Guard is used to control the access of Lazily loaded modules in the Angular application.

 

Conclusion

In this article, we explored canActivate and canLoad routing guards in Angular and demonstrated their implementation in a sample students app.

By implementing these guards, you can ensure that users only access the features they are allowed to use based on their roles or permissions. While canActivate is suitable for protecting regular routes, canLoad is best suited for securing lazy-loaded modules.

Leave a Comment

Your email address will not be published. Required fields are marked *