Angular functional router guard and testing with inject()
In Angular, guards are a fundamental feature that protects routes within an application. Guards check if certain conditions are met before allowing users to access specific routes. Guards can be used for authentication and authorization, role-based access control, feature flag checks, and more.
Angular provides several types of guards that can be used for different purposes, such as canActivate, canActivateChild, canDeactivate, and canLoad. These guards are defined as classes that implement specific interfaces provided by the Angular framework. When a guard is added to the canActivate array of a route, it is invoked before allowing the user to navigate to the desired route.
In this example, we have a Dashboard route that requires an admin role to access.
Traditional (Class) Router Guard
To prevent non-admin user from accessing this route, we can use a class guard as below.
Then we can apply the guard to routes.
This old approach works but based on the Angular survey:
We've received feedback from multiple developers that amounts to developers wanting less boilerplate and more productivity.
Which lead to the evolution of a functional router guard in Angular v14.
Functional router guards with
inject()
are lightweight, ergonomic, and more composable than class-based guards.
Functional router guard with inject()
The inject function is a new feature in Angular 14 that helps to inject external dependencies in our functions.
Registering the functional guard function is the same as class-based.
Testing functional guard
Testing guards in Angular is an essential part of the development process to ensure that the guards are working correctly and providing the desired functionality. To be honest, I couldn't find a lot of references in terms of testing inject() inside a functional router guard. Here is an example that works for me. The idea to mock inject()
inside @angular/core
package.
I hope that you find this post helpful. If you have any improvements, please leave a comment :)