As developers, we often find ourselves adapting to changes in the tools and frameworks we use. Recently, while working on my Angular project, I stumbled upon a significant shift in Angular 15: the deprecation of class-based route guards like CanDeactivate()
. In their place, Angular has introduced functional guards, providing a more modern and flexible approach to managing route deactivation. In this article, I'll guide you through this transition and share how you can smoothly update your codebase. β¨
Understanding the Change
In previous Angular versions, we used the CanDeactivate()
guard to handle route deactivation, implementing custom logic to determine whether a user could leave a particular route. However, Angular 15 introduces functional guards as the new way forward. This change aligns with Angular's mission to simplify and enhance the development experience.
Transitioning to Functional Guards
1) Create a Functional Guard: Start by creating a TypeScript function as your functional guard. This function should return true to allow deactivation or false to prevent it.
export const hasUnsavedChangesGuard: CanDeactivateFn<ComponentCanDeactivate> = (component: ComponentCanDeactivate): Observable<boolean> => {
if (component.canDeactivate && component.canDeactivate()) {
return true;
}
if (!component.confirm()) {
return confirm('Are you sure you want to leave this page? If you do, any unsaved changes will be lost.');
}
}
2) Implement the Functional Guard: In your routing configuration, specify the functional guard for a route.
const routes: Routes = [
{
path: 'my-component',
component: MyComponent,
canDeactivate: [hasUnsavedChangesGuard],
},
];
Alternatively, you can use an injectable class as a functional guard by leveraging the inject
function. This approach keeps your guard logic separate from your routing configuration, especially for the case you have your custom component such as Dialog component.
const routes: Routes = [
{
path: 'my-component',
component: MyComponent,
canDeactivate: [() => inject(hasUnsavedChangesGuard).canDeactivate()]
},
];
Conclusion
By embracing this change in Angular 15, you'll find your route guard implementation becomes more streamlined and adaptable. For detailed examples and additional information, refer to the official Angular documentation.
Change in the development world is inevitable, and adapting to it is key to staying at the forefront of technology. As I worked through this transition in Angular 15, I found it not only improved the development experience but also reinforced the idea that growth and improvement are constants in the world of software development. Embrace these changes, and you'll continue to build better, more maintainable applications ππ
Top comments (8)
So i'm upgrading from 15 to 18.. and its still deprecated ?
Why is the Angular community (google) so in love with deprecating instead of having things done multiple ways, each time a new design ideas comes out, they push anyone to follow it.
This isn't nice if you do large projects, and have to keep up with their avantgarde design goals.
If they deprecate and it is really needed (which i doubt a bit in this case), then say after date X we stop this functionality.. though that would alert people and they don't want to upset the public and run their language as if it was a fashion show.
Hey Peter, when I wrote the post, it was happened when I upgrade to v15 last year. After v15, you should refer to the latest official documentation: angular.dev/api/router/CanDeactivate.
getting no output whenever ng serve cmd run on terminal.
Hi Rahul, there could be various factors on whether deactivation is permitted. I've updated the post with guard and component logic examples. Also, You may check if you've correctly passed your guard in the module's providers (app.module.ts).
Here is the guide with application example from angular docs. I hope it helps.
here is screenshot!
this cmd didn't through any error dunring ng server runs command. and not starting this project.
It seems you're using a different Angular version and don't seem to be related to this article. Check out the link in my last reply about the application guide a look or just go ahead
npm install
again.Hello,
Could please share unit test for above code ?
Thanks in advance.
You can simply create a mock component has a
canDeactivate
method and ensure it works correctly :)