In my Angular 11 app, I am trying to implement a way to warn the user that there is unsaved data on the page.
For simplicity, let's consider that we only care when a user closes or refreshes the tab.
Basically, I was following the following implementation that was made in Angular 5: https://stackblitz.com/edit/angular-rgsa51?file=app%2Fform-can-deactivate%2Fform-can-deactivate.ts
I have a generic component that will handle the window:beforeunload
event:
@Directive()
export abstract class CanDeactivateComponent {
public abstract canDeactivate(): boolean;
@HostListener('window:beforeunload', ['$event'])
public unloadNotification($event: any): void {
console.log( '[CanDeactivateComponent] window:beforeunload ' );
if (!this.canDeactivate()) {
// triggers a browser confirmation dialog asking the user if they really want to leave the page
// most modern browsers will just present a generic message.
$event.returnValue = true;
}
}
}
And then, a component that is customized for Angular Forms:
export abstract class CanDeactivateFormComponent extends CanDeactivateComponent {
public abstract formGroup: FormGroup;
public abstract initialValue: {};
public canDeactivate(): boolean {
return JSON.stringify(this.initialValue) === JSON.stringify(this.formGroup.value);
}
}
My form component is implemented:
@Component({
...
})
export class MyFormComponent extends CanDeactivateFormComponent { ... }
The problem now is that thewindow:beforeunload
seeems to get triggered twice
(please check the console.log
message)
The full code is here: https://stackblitz.com/edit/angular-ivy-xu5vq8?file=src%2Fapp%2Fcan-deactivate.component.ts