FrancescoDonzello
Angular Share on Twitter

New in Angular v16: Guards Deprecation

3 minutes read
#articles#angular

With the release of Angular 16, Class Guards are being deprecated in favor of Functional Guards.

In this article, we will delve into the changes and discuss the benefits of adopting Functional Guards, including how they compare to the now-deprecated Class Guards.

Class Guards in Angular 15

Up to Angular 15, Class Guards were the primary mechanism for protecting routes based on certain conditions, such as user authentication or authorization.

These classes contained a method, such as canActivate, which would return a boolean or an observable or promise that resolved to a boolean, determining if the route could be accessed.

import { inject, Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angular/router';
import { AuthService } from './auth.service';
 
@Injectable({
  providedIn: 'root'
})
export class DenyGuestsGuard implements CanActivate {
  private readonly isLoggedIn$ = inject(AuthService).isLoggedIn$
 
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot) {
 
    return this.isLoggedIn$;
  }
}

Functional Guards in Angular 15

Functional Guards were introduced in Angular 15 as an alternative to Class Guards. They are essentially pure functions that take in the same arguments as their Class Guard counterparts and return the same boolean or observable or promise that resolves to a boolean.

Functional Guards offer a more lightweight and functional approach to route protection.

import { inject } from '@angular/core';
import { CanActivateFn } from '@angular/router';
import { AuthService } from './auth.service';
 
export const denyGuestsGuard: CanActivateFn = (route, state) => {
  return inject(AuthService).isLoggedIn$;
};

The inject function works fine on Functional Guards so that we can inject what we need.

The amount of code required for Functional Guards is really winning over Class Guards.

Deprecation of Class Guards in Angular 16

With the release of Angular 16, Class Guards are being deprecated in favor of Functional Guards. This decision stems from the advantages of Functional Guards, such as improved tree-shaking, better type inference, and a more functional programming approach.

However, it’s important to note that Class Guards will continue to work for some time, giving developers the opportunity to migrate their code to the new Functional Guards.

If you update your project using ng update, and you should, the schematic will automatic update your code by using the new map* functions that transform Class Guards into Functional Guards.

Here’s an example:

import { inject, Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, mapToCanActivate } from '@angular/router';
import { AuthService } from './auth.service';
 
@Injectable({
  providedIn: 'root'
})
export class DenyGuestsGuard implements CanActivate {
  private readonly isLoggedIn$ = inject(AuthService).isLoggedIn$
 
  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot) {
 
    return this.isLoggedIn$;
  }
}
 
export const denyGuestsGuard = mapToCanActivate([DenyGuestsGuard])

Considerations

The deprecation of Class Guards in Angular 16 pushes the framework toward a less verbose approach.

Although the transition may require some refactoring, automated if you use ng update, the benefits of using Functional Guards are evident.

← Back to Angular Articles

Was it helpful?

Tell your friends or co-workers.