• Angular
  • React
  • NextJs
  • Sass

How to use canActivateChild in Angular

By Webrecto, September 09, 2023

The canActivateChild functional route guard is one of the most important concepts of Angular.

1. The canActivateChild route guard controls, if the current user is allowed to activate a child of the component. It accepts Array <CanActivateChildFn> type data.

2. In the application, the canActivateChild is used for user authorization.

3. We apply the canActivateChild guard to the parent route.

4. Whenever the user try to navigate child route, Angular activate this route guard.

5. The route guard checks some conditions in the method and it decides whether the current user can access the route path or not.

6. If the current user navigates the child route, and the guard inside canActivateChild returns true, then the user can access the URL.

7. Whenever the method returns false to the current user, then the user can not access the URL.

Code Snippet:

canActivateChild: [
      (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) =>
        inject(AuthGuardService).canActivateChild(route, state)
    ]

The inject function helps to inject external dependencies in functions. We call canActivateChild method inside inject function.

Using canActivateChild:

1: We create an auth-guard.service file, and using the canActivateChild route guard to control child component access. In this service file, we create one canActivateChild method. In this method, we check the user authorization to a certain path.

canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    let loggedInUser = this.authService.getLoggedInUser();
    if (oggedInUser.role === 'Admin' || loggedInUser.role === 'Customer') {
        return true;
    } else {
        alert("You are not authorized to visit the customer section!")
        return false;
    }
}

2: In Routing module, We use the canActivateChild route guard in the parent route, where we need to control access for users.

 path: 'customer',
    loadChildren: () => import('../customer/customer.module').then(mod => mod.CustomerModule),
    canActivateChild: [
      (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) =>
        inject(AuthGuardService).canActivateChild(route, state)
 ]

Complete Example:

In this example, I will create one demo application and inside I will create login and dashboard components for use canActivateChild.

1: I created two feature modules inside the dashboard folder and created a navigation for accessing feature modules in the dashboard component.

2: In the auth.service file, I created three users and provided different roles. I will provide access to the feature module on the basis of the role.
Admin -> login - admin, pass - admin (Supper admin)
employee -> login - santosh, pass - s123(employee)
customer -> login - mohan, pass - m123

3: I configured the canActivateChild method in the dashboard.routing.module. In the module, I added two route paths for the access feature module, one is the employee path and the other is the customer path.

4: I added the canActivateChild method in the customer path to prevent access when employees login. Only the admin and customer can access the customer route path.

5: When an employee login, he can not access the customer feature module. Because he is not authorized to access.

dashboard.routing.module.ts

import { NgModule, inject } from '@angular/core';
import { ActivatedRouteSnapshot, RouterModule, RouterStateSnapshot, Routes } from '@angular/router';
import { AuthGuardService } from '../authentication/services/auth-guard.service';

const dashboardRoutes: Routes = [
  {
    path: 'employee',
    loadChildren: () => import('../employee/employee.module').then(mod => mod.EmployeeModule)
  },
  {
    path: 'customer',
    loadChildren: () => import('../customer/customer.module').then(mod => mod.CustomerModule),
    canActivateChild: [
      (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) =>
        inject(AuthGuardService).canActivateChild(route, state)
    ],
  }
];

@NgModule({
  imports: [ RouterModule.forChild(dashboardRoutes) ],
  exports: [ RouterModule ]
})
export class DashboarRoutingModule { }

auth-guard.service.ts

import { Injectable } from '@angular/core';
import { Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable()
export class AuthGuardService {

	constructor(private authService: AuthService, private router: Router) {
	}
	canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
		let url: string = state.url;
		if (this.authService.isUserLoggedIn()) {
			return true;
		}
		this.authService.setRedirectUrl(url);
		this.router.navigate([this.authService.getLoginUrl()]);
		return false;
	}
	canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
		let loggedInUser = this.authService.getLoggedInUser();
		if (loggedInUser.role === 'Admin' || loggedInUser.role === 'Customer') {
			return true;
		} else {
			console.log('Unauthorized to open link: ' + state.url);
			alert("You are not authorized to visit the customer section!")
			return false;
		}
	}
}

auth.service.ts

const USERS = [
	new User(1, 'admin', 'admin', 'Admin'),
	new User(2, 'santosh', 's123', 'Employee'),
	new User(2, 'mohan', 'm123', 'Customer')
];

dashboard.component.html

<div class="row">
    <div class="col-md-12 header-menu">
        <ul>
            <li><a routerLink="/">Home</a></li>
            <li><a routerLink="/dashboard/employee" routerLinkActive="active">Employee</a></li>
            <li><a routerLink="/dashboard//customer" routerLinkActive="active">Customer</a></li>
        </ul> 
        <div class="logout">
           <logout></logout>
        </div>   
    </div>
    <div class="col-md-12 pt-4">
        <h4>Dashboard:: webrecto.com</h4>
        
        <router-outlet></router-outlet>
    </div>
</div>

Find the print screen of the output.

I am login from santosh user id

How to use canactivatechild in angular

When an employee user clicks on the customer path from navigation, he can not access it and will find the unauthorized user access message.

How to use canactivatechild in angular

Reference

Download Source Code