Conditional Guard with Angular

I use CanDeactivate in one of my projects to prevent the user from leaving a form that has unsaved changes which is indicated by its dirty state. Whenever there are still unsaved changes a confirmation message is displayed. Unfortunately the message was also displayed in inappropriate cases e.g. when the user is logged out because his session expired. To prevent this I did some research and came up with pretty simple solution.

dirty-check.guard.ts import { Injectable } from '@angular/core'; import { of, Observable } from 'rxjs'; import { mergeMap } from 'rxjs/operators'; import { DirtyComponent } from '../components/dirty.component'; import { MessageService } from '../services/message.service'; import { Router } from '@angular/router'; @Injectable({ providedIn: 'root' }) export class DirtyCheckGuard { constructor(private readonly messageService: MessageService, private readonly router: Router ) { } canDeactivate(component: DirtyComponent): Observable<boolean> { const ignoreDirtyCheck = this.router.getCurrentNavigation()?.extras?.state?.['ignoreDirtyCheck'] as boolean; if(ignoreDirtyCheck) { return of(true); } if (component?.isDirty) { return component.isDirty .unsubscribeOnDestroy(component) .pipe( mergeMap((value) => { if (value) { return this.messageService.openDirtyConfirm(component); } return of(true); })); } else { return of(true); } } }

By using the NavigationExtras we can pass custom values into the router like this:

this.router.navigateByUrl('login', { state: { ignoreDirtyCheck: true } });

So whenever I want to navigate and "ignore" the guard, I just have to pass the custom flag inside the state object.