The solution depends on why you want to prevent the page reload. If you want to prevent it because there can be unsaved changes you have actually to prevent two different behaviours:
- Browser page reload. You can achieve this by creating an HostListener on the beforeunload event (similar to your attempt) like:
@HostListener('window:beforeunload', ['$event'])
beforeUnloadHander() {
// or directly false
this.allowRedirect;
}
- Angular routing change (if you have routing): to do that you have to use a Deactivation guard on the route you want to lock, there are many ways but the most appreciated is the one that uses an interface implementation:
I. The interface sets up a couple of fields used in the angular guard to check if the we can change the router path:
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;
}
II. Each component has to implement this interface with the method canDeactivate or the allowRedirect field (reusable in the HostListener for the problem #1) and must returning a boolean that indicates if navigation is allowed or not.
III. Create a router guard that checks this component fields for the deactivation:
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;
}
}
III. Set the canDeactivate router guard in your module.routing.ts file:
const myRoutes: Routes = [
{
path: "locked-route-path",
component: ComponentThatImplementsLockedInterface,
canDeactivate: [TheCanDeactivateGuardJustMade]
}
//...
]