Using CanActivateFn in Angular 17
Angular development demands security and control over navigation activity. This article goes into two critical Angular Guards enhancements: the switch from implementing the CanActivate interface to using CanActivateFn. These enhancements provide developers with a simpler, more effective method to protect routes while imposing role-based access control.
Guards act as guardians in Angular apps, limiting accessibility to specific routes based on defined constraints. They play an important role in implementing authentication, authorization, and other navigation rules. Their utility is in protecting routes from unwanted access or improper navigation.
Route guards are used in Angular for authorizing or denying access to specific routes. The CanActivateFn
function provides a functional alternative to building route guards that allow or deny access to specified routes based on certain conditions. In this post, we will look at how to work with CanActivateFn
in Angular and provide practical examples of how to use it to protect routes or parts of our Angular application.
Topics:
- What is Angular CanActivateFn?
- Signature of CanActivateFn
- CanActivate in Route Configuration
- Using mapToCanActivate for Class-Based Guards
- Using CanActivateFn in Angular 17 Applications
- Add a CanActivateFn Function
- Use canActivate in Route Configuration
- Using mapToCanActivate for Old Class Guards
- Conclusion
Previously, guards were interfaces that had to be implemented and registered in your modules.
However, in the most recent versions of Angular, class-based guards have been deprecated in favor of functional guards.
To achieve the same result as implementing an interface, a function can now be used instead.
What is Angular CanActivateFn?
CanActivateFn
is a function that acts as a route guard that is passed to the canActivate
property in Angular's routing setup. It allows developers to specify the requirements that must be fulfilled before going to a specific route.
Signature of CanActivateFn
The CanActivateFn
function accepts the following parameters.
route
: An activatedRoute
object that contains information about the current route.state
: The currentRouterStateSnapshot
, which contains information about the router's current state, including the URL and other metadata.
The function can return a Observable, a Promise, or a boolean value that determines if the route can be accessed or activated.
CanActivate in Route Configuration
The canActivate
attribute of the Route
interface defines an array of CanActivateFn
functions to be used as route guards. If any of these functions return false, access to the route is denied.
Using mapToCanActivate for Class-Based Guards
Angular offers the mapToCanActivate
function, which allows you to convert classes with a canActivate
method into an array of corresponding CanActivateFn
functions. This helps to incorporate the previous class-based route guards and facilitates switching to the new functional model.
Using CanActivateFn in Angular 17 Applications
To see an example of CanActivateFn
in an Angular 17 application, let us take these steps.:
1. Add a CanActivateFn Function
Write a function that returns a boolean, Observable<boolean>
, or Promise<boolean>
. It will be used to check whether a route can be accessed. This is the code example:
import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { AuthService } from './auth.service';
export const authGuard: CanActivateFn = (route, state) => {
const authService = inject(AuthService);
const router = inject(Router);
if (authService.isLoggedIn()) {
return true;
}
router.navigate(['/login']);
return false;
};
We define an authGuard
function of type CanActivateFn
which takes the route and state as parameters. In the body of the guard, we inject the router and authentication service and check if the user is logged in. In this case we return true otherwise we use the navigate()
method of the router to navigate to the login URL and we return false from the CanActivateFn
function.
2. Use canActivate in Route Configuration
After writing the CanActivateFn
function, we need to add it to the route configuration to protect routes. Here is an example routes file
import { Routes } from '@angular/router';
import { LoginComponent } from './pages/login/login.component';
import { SignupComponent } from './pages/signup/signup.component';
import { AdminComponent } from './pages/admin/admin.component';
import { authGuard } from './auth/auth.guard';
export const routes: Routes = [
{
path: '', redirectTo: '/login', pathMatch: 'full'
},
{
path: 'login', component: LoginComponent
},
{
path: 'signup', component: SignupComponent
},
{
path: 'admin', component: AdminComponent, canActivate: [authGuard]
}
];
Notice that the admin component is protected by the authGuard
function. If the function returns false
, navigation to the AdminComponent
is denied.
Using mapToCanActivate for Old Class Guards
If you have class-based guards with a canActivate
method, you have to use mapToCanActivate
to convert them into CanActivateFn
functions. For example:
import { mapToCanActivate } from '@angular/router';
import { AuthGuard } from './guards/authguard.guard';
const authGuard = mapToCanActivate([AuthGuard]);
const routes: Routes = [
{ path: 'admin', component: AdminComponent, canActivate: authGuard },
];
Here, mapToCanActivate
converts AuthGuard
into a CanActivateFn
function that can be used in the functional approach.
Conclusion
When developing a web application, it is likely that you will use routing at some time.
However, lost often not all routes may be accessed by everyone. For example, you might not allow an anonymous user to access the admin page of the application. Angular, like many other frameworks, has addressed this issue.
In this article, we've looked at what guards are, how to utilize them, and some specific use cases in various settings where route guards shine.
To summarize, CanActivateFn
is a versatile and modern way to build route guards in Angular 17. It provides a straightforward functional way, with the flexibility to inject services and add complex conditional logic. The canActivate
attribute in route configurations enables you to add arrays of CanActivateFn
functions, giving you powerful ways in protecting your components. The mapToCanActivate
function is handy for migrating from old class-based guards to the new functional approach while maintaining backward compatibility.
-
Date: