CanDeactivate
?CanDeactivate
is a route guard that is used to prevent a user from leaving the current route, especially if there are unsaved changes. It’s particularly useful in scenarios where you want to prevent accidental navigation away from forms, ensuring that users do not lose their progress without warning.
Unlike the CanActivate
or CanActivateChild
guards, which are used to protect access to a route, the CanDeactivate
guard protects users from navigating away from a route.
CanDeactivate
1. Preventing Loss of Unsaved Data: When users are filling out a form, you can use CanDeactivate
to ask for confirmation before leaving the page if the form has unsaved changes.
2. Form Validation: It can also be useful to prevent navigation away from a route if the form data is invalid, ensuring the user corrects the mistakes before leaving.
3. Session Timeout Warning: You can alert users that their session is about to expire when they try to navigate away, giving them a chance to save their work or extend the session.
Setting Up the CanDeactivate
Guard in Angular
Step 1: Create the Guard
ng generate guard auth/form-deactivate
CanDeactivate
Interfaceimport { Injectable } from '@angular/core'; import { CanDeactivate } from '@angular/router'; import { Observable } from 'rxjs'; // The interface the component must implement export interface CanComponentDeactivate { canDeactivate: () => boolean | Observable<boolean>; } @Injectable({ providedIn: 'root', }) export class FormDeactivateGuard implements CanDeactivate<CanComponentDeactivate> { canDeactivate(component: CanComponentDeactivate): boolean | Observable<boolean> { // Check if there are unsaved changes return component.canDeactivate() || confirm('You have unsaved changes. Do you really want to leave?'); } }
Here’s what’s happening in the code:
CanComponentDeactivate
that requires a canDeactivate
method to be implemented by any component guarded by this guard.canDeactivate
method is invoked when a user attempts to navigate away from the current route.false
, navigation is prevented. Otherwise, if true
or the user confirms, navigation proceeds.Step 3: Implement CanDeactivate
Logic in the Component
import { Component } from '@angular/core'; import { CanComponentDeactivate } from './auth/form-deactivate.guard'; @Component({ selector: 'app-profile-edit', templateUrl: './profile-edit.component.html', }) export class ProfileEditComponent implements CanComponentDeactivate { formHasUnsavedChanges = false; // Called when the user attempts to leave the page canDeactivate(): boolean { // Check if there are unsaved changes return !this.formHasUnsavedChanges; } // Simulate form changes onFormChange() { this.formHasUnsavedChanges = true; } // Simulate form submission saveForm() { this.formHasUnsavedChanges = false; } }
Here’s the breakdown:
canDeactivate
method returns false
if there are unsaved changes, which will trigger the confirmation dialog.formHasUnsavedChanges
is a simple flag that gets set to true
when the form is modified and reset to false
when the form is saved.Step 4: Applying the CanDeactivate
Guard to Routes
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { ProfileEditComponent } from './profile-edit/profile-edit.component'; import { FormDeactivateGuard } from './auth/form-deactivate.guard'; const routes: Routes = [ { path: 'edit-profile', component: ProfileEditComponent, canDeactivate: [FormDeactivateGuard], }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], }) export class AppRoutingModule {}
With everything set up, test the implementation:
1. Navigate to the /edit-profile
route.
2. Make some changes to the form.
3. Attempt to navigate to a different route or refresh the page. You should see a confirmation dialog warning you about unsaved changes.
CanDeactivate
The CanDeactivate
guard is versatile and can be extended for a variety of use cases:
1. Custom Confirmation Dialogs: You can replace the standard confirm()
dialog with a custom modal that provides more detailed options to the user, such as saving their changes before leaving.
2. Form Validation: Use the guard to block navigation if the form contains invalid data, forcing users to fix errors before moving away.
3. Session Expiry Alerts: If a user’s session is about to expire, you can warn them via the CanDeactivate
guard when they try to leave the page, offering a chance to save their work or renew the session.