Skip to content

Instantly share code, notes, and snippets.

@navix
Last active November 23, 2022 09:18
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save navix/ad7f73eaea0a5180416768424cff823c to your computer and use it in GitHub Desktop.
Save navix/ad7f73eaea0a5180416768424cff823c to your computer and use it in GitHub Desktop.
Prevent leaving from any page using Router in Angular 7

Prevent leaving from any page using Router in Angular 7

Angular has CanDeactivate guard, but you have to declare it to each path in the routes configuration.

Valid until angular/angular#11836 will be done.

You can use CanActivateChild guard to prevent leaving from any component with single declaration.

leave-guard.service.ts

import { Location } from '@angular/common';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivateChild, NavigationStart, Router, RouterStateSnapshot } from '@angular/router';

@Injectable({
  providedIn: 'root',
})
export class LeaveGuardService implements CanActivateChild {
  canLeave = true;

  lastTrigger: 'imperative' | 'popstate' | 'hashchange';

  constructor(
    private router: Router,
    private location: Location,
  ) {
    this.router.events.subscribe(event => {
      if (event instanceof NavigationStart) {
        this.lastTrigger = event.navigationTrigger;
      }
    });
  }

  canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    // Fix browser history if leaving prevented and called by back/forward navigation
    if (!this.canLeave && this.lastTrigger === 'popstate') {
      this.location.go(state.url);
    }
    return this.canLeave;
  }
}

Wrap all your paths into dummy:

const routes: Routes = [
  {
    path: '',
    canActivateChild: [LeaveGuardService],
    children: [
      ...
    ],
  },
];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment