Preventing Accidental Data Loss in Angular:......

Preventing Accidental Data Loss in Angular: Mastering the CanDeactivate Guard

Preventing Accidental Data Loss in Angular: Mastering the CanDeactivate Guard

What is 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.


Key Use Cases for 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


Step 2: Implement the CanDeactivate Interface


import { 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:


  • We define an interface CanComponentDeactivate that requires a canDeactivate method to be implemented by any component guarded by this guard.


  • The canDeactivate method is invoked when a user attempts to navigate away from the current route.


  • If the method returns 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:


  • The 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 {}


Step 5: Testing the Guard


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.


Advanced Use Cases for 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.


Share Article:
  • Facebook
  • Instagram
  • LinkedIn
  • Twitter
  • Recent Posts