Reputation: 3
I'm using Angular 12 SPA app. When user press the browser back button. I want to show the warning message before leave in current route url. Current page "localhost/note"
If user click back button. url changed "localhost/home" then show the warning message(page is not changed, only url changed)
However, I want to show the message BEFORE route change. I'm using HostListener. It shows alert after url/route change
@HostListener('window:popstate', ['$event'])
onPopState(event: any) {
alert("Do you really want to move other page?");
}
Upvotes: 0
Views: 5202
Reputation: 3228
welcome to the stackoverflow. What you are looking for is onbeforeunload
event, it should do the job. But check it here, some browsers have limitations for it (like blocking pop-ups).
@Directive()
export abstract class ComponentCanDeactivate {
abstract canDeactivate(): boolean;
@HostListener('window:beforeunload', ['$event'])
unloadNotification($event: any) {
if (!AuthService.isLogout && !this.canDeactivate()) {
$event.returnValue = true;
}
}
}
We used the code above together with a route guard which check Angular Router navigation. If result of canDeactivate
is false
, route guard won't let you leave the current route.
@Injectable({
providedIn: 'root',
})
export class UnsavedChangesGuard implements CanDeactivate<ComponentCanDeactivate> {
constructor() {}
canDeactivate(
component: FormCanDeactivate,
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
next: RouterStateSnapshot
): boolean | Observable<boolean> {
const someUrlCheck = next.url.includes(someRoute);
return component.canDeactivate() ? true : component.openConfirmCancelDialog(someUrlCheck);
}
}
In our case FormCanDeactivate
abstract class extends another ComponentCanDeactivate
abstract class and provides default 'Are you sure you want to leave' dialog.
@Directive()
export abstract class FormCanDeactivate extends ComponentCanDeactivate {
private _dialogConfig: ConfirmDialogData = initialDialogConfig;
protected disableDiscard: boolean = false;
get dialogConfig(): ConfirmDialogData {
return this._dialogConfig;
}
set dialogConfig(value: ConfirmDialogData) {
this._dialogConfig = value;
}
abstract get saveForm(): FormGroup | boolean;
abstract submitForm(): void;
abstract resetForm(): void;
constructor(protected dialog: MatDialog) {
super();
}
openConfirmCancelDialog(isLogout: boolean = false): Observable<boolean> {
// ...
}
canDeactivate(): boolean {
// ...
}
}
Upvotes: 1