I only have a few weeks of experience in angular. This is my workaround. I added the variable check for unsaved form in local storage.
<---------------------------------------------------------------------------------->
header.component.ts
logout(){
this.formDetect= JSON.parse(localStorage.getItem('formDetect'));
var res=true;
if(this.formDetect.isUnsaved){
res=confirm("are you sure you want to logout? You have an unsaved form");
}
if(res){
//If you are using it somewhere else, make sure to set isUnsaved to false then set local storage.
//this.formDetect.isUnsaved=false;
//localStorage.setItem("formDetect", JSON.stringify(this.formDetect));
this.accountService.logout();
this.router.navigateByUrl('/login');
}
}
<---------------------------------------------------------------------------------->
form.component.ts
export class FormComponent implements OnInit, SafeData {
formDetect:FormDetect;
@HostListener('window:beforeunload')
isDataSaved():boolean{
this.formDetect= JSON.parse(localStorage.getItem('formDetect'));
return!this.formDetect.isUnsaved;
}
onFormChange(){
this.formDetect.isUnsaved=true;
localStorage.setItem("formDetect", JSON.stringify(this.formDetect));
}
}
<---------------------------------------------------------------------------------->
export interface SafeData{
isDataSaved():boolean;
}
<---------------------------------------------------------------------------------->
export class FormDetect{
isUnsaved:boolean=false;
}
<---------------------------------------------------------------------------------->
Guard
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanDeactivate, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { SafeData } from '../_models/safeData';
@Injectable({
providedIn:"root"
})
export class UnsavedCheckGuard implements CanDeactivate<SafeData> {
canDeactivate(component: SafeData): boolean | Observable<boolean> {
// if there are no pending changes, just allow deactivation; else confirm first
var result= component.isDataSaved();
return result ?
true :
// NOTE: this warning message will only be shown when navigating elsewhere within your angular app;
// when navigating away from your angular app, the browser will show a generic warning message
// see https://mcmap.net/q/136686/-candeactivate-confirm-message
confirm('You have unsaved changes. Press Cancel to go back and save these changes, or OK to lose these changes.');
}
}
canDeactivate
route guard on your current route. In the callbackgetLogoutConfirmation
, you can show the modal and return a promise to confirm/cancel the logout. You can also have guards on the login route but they are not relevant in your question. – Illaudable