Lab 08: Deactivate Guard
📖 Resources
Section titled “📖 Resources”🚀 Starter Code
Section titled “🚀 Starter Code”step-5-album-wholesale-v16-post-add-custom-async-validator
Continue from your Lab 07 result. If you need a fresh copy, use step-5-album-wholesale-v16-post-add-custom-async-validator as your base and complete Labs 05–07 first.
In this lab, you’ll prevent users from accidentally losing unsaved form data by implementing a CanDeactivate guard. You’ll create a functional guard that prompts users for confirmation, implement the deactivation logic in your component, and optionally replace browser confirm dialogs with Material Dialog.
📝 Instructions
Section titled “📝 Instructions”Step 1: Create Deactivate Guard
Section titled “Step 1: Create Deactivate Guard”Create a functional guard:
import { CanDeactivateFn } from '@angular/router';
export interface CanComponentDeactivate { canDeactivate: () => boolean;}
export const canDeactivateGuard: CanDeactivateFn<CanComponentDeactivate> = (component) => { if (component.canDeactivate && !component.canDeactivate()) { return confirm('You have unsaved changes. Leave anyway?'); } return true;};Step 2: Implement in Component
Section titled “Step 2: Implement in Component”Add canDeactivate method to component:
export class AlbumAddComponent implements CanComponentDeactivate { private formSubmitted = false;
canDeactivate(): boolean { return !this.albumForm.dirty || this.formSubmitted; }
saveAlbum() { this.formSubmitted = true; // Save logic... }}Step 3: Apply to Route
Section titled “Step 3: Apply to Route”Add guard to route:
const routes: Routes = [ { path: 'albums/add', component: AlbumAddComponent, canDeactivate: [canDeactivateGuard] }];Bonus Step: Use MatDialog Instead of confirm()
Section titled “Bonus Step: Use MatDialog Instead of confirm()”Replace browser confirm() with Material Dialog:
import { inject } from '@angular/core';import { MatDialog } from '@angular/material/dialog';import { ConfirmDialogComponent } from './confirm-dialog.component';
export const canDeactivateGuard: CanDeactivateFn<CanComponentDeactivate> = (component) => { if (component.canDeactivate && !component.canDeactivate()) { const dialog = inject(MatDialog);
return dialog.open(ConfirmDialogComponent, { data: { message: 'You have unsaved changes. Leave anyway?' } }).afterClosed(); } return true;};Simple confirmation dialog component:
@Component({ selector: 'app-confirm-dialog', template: ` <h2 mat-dialog-title>Confirm</h2> <mat-dialog-content>{{ data.message }}</mat-dialog-content> <mat-dialog-actions> <button mat-button [mat-dialog-close]="false">Cancel</button> <button mat-button [mat-dialog-close]="true" color="warn">Leave</button> </mat-dialog-actions> `})export class ConfirmDialogComponent { data = inject(MAT_DIALOG_DATA);}
