liveBook · Manning

Route deactivation guard

As explained in Pro Angular 16

A route deactivation guard is an Angular guard that determines whether the currently displayed component may be left during navigation.

A route deactivation guard decides whether the currently displayed component may be left during navigation. Its common role is protecting unsaved edits: inspect the component, warn when its form is dirty, and allow or reject navigation. section 26.2.2

Implement the guard by:

  • Defining a class with canDeactivate(component, route, state), receiving the component and route snapshots. section 26.2.2
  • Checking editing state and productForm.dirty before prompting the user. section 26.2.2
  • Returning a boolean or Promise<boolean>; resolve the promise from the user's Yes or No response. section 26.2.2
  • Registering the guard as a service and attaching it to the route with canDeactivate. section 26.2.2

Unsaved product edits

When a user edits a product and navigates away, the guard checks editing and productForm.dirty. If both indicate unfinished work, it presents Yes and No responses; Yes permits navigation, while No keeps the current route active. section 26.2.2

Listing 26.15. The contents of the unsaved.guard.ts file in the src/app/core folder
import { Injectable } from "@angular/core";
import { ActivatedRouteSnapshot, RouterStateSnapshot, Router } 
    from "@angular/router";
import { MessageService } from "../messages/message.service";
import { Message } from "../messages/message.model";
import { FormComponent } from "./form.component";
 
@Injectable()
export class UnsavedGuard {
 
    constructor(private messages: MessageService,
                private router: Router) { }
 
    canDeactivate(component: FormComponent, route: ActivatedRouteSnapshot,
            state: RouterStateSnapshot): Promise<boolean> | boolean {
        if (component.editing && component.productForm.dirty) {
            return new Promise(resolve => {
                let responses: [string, (r: string) => void][] = [
                    ["Yes", () => resolve(true)],
                    ["No", () => {
                        this.router.navigateByUrl(this.router.url);
                        resolve(false);
                    }]
                ];
                this.messages.reportMessage(
                    new Message("Discard Changes?", true, responses));
            });
        }
        return true;
    }
}

Browse the UnsavedGuard implementation, including its canDeactivate method and response-driven Promise. section 26.2.2

How Pro Angular 16 covers it

How deep it goes
Explains component checks, route snapshots, Promise results, service registration, and route attachment.
Examples
Uses a product-edit form whose dirty state triggers a Yes-or-No navigation prompt.
What it assumes
Assumes Angular routing and component form state, while teaching guard arguments and registration.
What you can do after
Operate/configure Angular routing to warn about unsaved edits and reject navigation when appropriate.
How it connects
Connects Angular routing with route activation guards, reactive forms, ActivatedRouteSnapshot, RouterStateSnapshot, and Promise results.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Pro Angular 16. The section links point to the parts of the book it draws on.