Skip to content

Instantly share code, notes, and snippets.

@HighSoftWare96
Created February 13, 2020 09:58
Show Gist options
  • Save HighSoftWare96/4cd6380371553e3f37b227ae7431db92 to your computer and use it in GitHub Desktop.
Save HighSoftWare96/4cd6380371553e3f37b227ae7431db92 to your computer and use it in GitHub Desktop.
Angular prevent page refresh and route deactivation

How to prevent Angular page refresh?

Quick guide about how lock an Angular page both in the Angular route and the browser refresh. Reference: https://stackoverflow.com/a/55470623/7387126

Component interface: LockableComponent

import { Observable } from "rxjs";
import { HostListener } from "@angular/core";

// see https://scotch.io/courses/routing-angular-2-applications/candeactivate
// implementing this interface with a component in angular you can implement a candeactivate
// guard that automatically checks if there is the canDeactivate function and
// it allows to navigate out of the route or not
export default interface LockableComponent {
  allowRedirect: boolean;
    canDeactivate(): boolean;
  }

Universal canDeactivate guard for LockableComponent

  canDeactivate(
    component: LockableComponent,
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot
  ): Observable<boolean> | Promise<boolean> | boolean {
    if (
      (component.allowRedirect === false ||
        (component.canDeactivate && !component.canDeactivate()))
    ) {
      // Angular bug! The stack navigation with candeactivate guard
      // messes up all the navigation stack...
      // see here: https://github.com/angular/angular/issues/13586#issuecomment-402250031
      this.location.go(currentState.url);

      if (
        window.confirm("Sure man?")
      ) {
        return true;
      } else {
        return false;
      }
    } else {
      return true;
    }
  }

Inside Angular component

// ... component extends LockableComponent
allowRedirect: boolean;

canDeactivate(): boolean {
  return this.allowRedirect;
}

@HostListener('window:beforeunload', ['$event'])
beforeUnloadHander() {
    // or directly false
    this.allowRedirect;
}

Inside Angular router

const myRoutes: Routes = [
      {
        path: "locked-route-path",
        component: ComponentThatImplementsLockedInterface,
        canDeactivate: [TheCanDeactivateGuardJustMade]
      }
      //...
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment