Angular 15: Transitioning deprecated CanDeactivate() to Functional Guards

junlow

jun

Posted on September 7, 2023

Angular 15: Transitioning deprecated CanDeactivate() to Functional Guards

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.');
    }
}
Enter fullscreen mode Exit fullscreen mode

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],
  },
];
Enter fullscreen mode Exit fullscreen mode

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()]
  },
];
Enter fullscreen mode Exit fullscreen mode

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 πŸ˜„πŸš€

πŸ’– πŸ’ͺ πŸ™… 🚩
junlow
jun

Posted on September 7, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related