The canActivate method implementation via the implements CanActivate class in the child class is deprecated since Angular v.15.

Instead, we have to call this function directly from our routing module file where the declaration of the component happens.

Solution I

// Routing Module File.ts


// Example 1 ~ Without parameters

{
    path: 'Dashboard',
    canActivate: [() => inject(AuthGuard).canActivate()], // AuthGuard is your same class as it was before
    component: DashboardComponent 
}



// Example 2 ~ With parameters

{
    path: 'Dashboard',
    canActivate: [(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) => inject(AuthGuard).canActivate(next, state)],
    component: DashboardComponent

Solution II – (Recommended by Angular Documentation)

(based on: https://angular.io/guide/router#preventing-unauthorized-access)

old :

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {

  constructor(private router: Router) {}

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean 
  {
    //your logic goes here
  }
}

base on: https://angular.io/guide/router#preventing-unauthorized-access

old:

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {

  constructor(private router: Router) {}

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean 
  {
    //your logic goes here
  }
}

new:

@Injectable({
  providedIn: 'root'
})
class PermissionsService {

  constructor(private router: Router) {}

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
      //your logic goes here
  }
}

export const AuthGuard: CanActivateFn = (next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean => {
  return inject(PermissionsService).canActivate(next, state);
}

there is no need to change in our routes and we can use it same as old:

{
    path: 'Dashboard',
    canActivate: [AuthGuard],
    component: DashboardComponent
  }

PS: We can also rename the AuthGuard function, then we will have to adapt the naming in our routes..

@Injectable({
  providedIn: 'root'
})
class PermissionsService {

  constructor(private router: Router) {}

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
      //your logic goes here
  }
}

const canActivateTeam: CanActivateFn =
    (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
      return inject(PermissionsService).canActivate(inject(UserToken), route.params.id);
    };

now, we adapt the routing modules:

bootstrapApplication(App, {
  providers: [provideRouter([
    {
      path: 'Dashboard',
      component: DashboardComponent,
      canActivate: [canActivateTeam],
    },
  ])]
});

By Shabazz

Software Engineer, MCSD, Web developer & Angular specialist

Leave a Reply

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