I'm trying to prevent navigation until the user confirms they will lose their changes, but I don't think I can use a route guard in my scenario.
Here is the check for changes:
public get hasChanged(): boolean {
return this.changeManager.hasChanged({
propA: this.propACtrl.value,
propB: this.propBCtrl.value,
// ETC, lots of other checks
});
}
class ChangeManager {
// bunch of properties containing original values
public hasChanged(args: ChangeManagerArguments): boolean {
return this.propA !== args.propA || this.propB !== args.propB // etc...
}
}
Therefore, I don't think I can use a service, since this check is done at a specific timing, the service will not have that information (since it doesn't have access to all those properties it needs to check).
For the moment, I can handle the scenario where the user uses the browser features to leave the page (back button, home button, closing tab etc...) by doing this:
@HostListener("window:beforeunload")
public unloadHandler(): boolean {
if (this.hasChanged) {
return false;
}
return true;
}
How can I have something similar if the user navigates via a routerLink? Is there a way to achieve this with a route guard?
CodePudding user response:
First need to create PendingChangesGuard as below:
export interface ComponentCanDeactivate {
canDeactivate: () => boolean | Observable<boolean>;
}
@Injectable()
export class PendingChangesGuard implements CanDeactivate<ComponentCanDeactivate> {
canDeactivate(component: ComponentCanDeactivate,
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
nextState: RouterStateSnapshot): boolean | Observable<boolean> {
// if there are no pending changes, just allow deactivation; else confirm first
return component.canDeactivate() ?
true :
confirm('WARNING: You have unsaved changes. Press Cancel to go back and save these changes, or OK to lose these changes.');
}
}
Routing Path add Guard
{ path: 'path...', component: ComponentName, canDeactivate: [PendingChangesGuard] },
//Write below code in component where you want to check the change done or not?
@HostListener('window:beforeunload')
canDeactivate(): Observable<boolean> | boolean {
// insert logic to check if there are pending changes here;
// returning true will navigate without confirmation
// returning false will show a confirm dialog before navigating away
if(this.list.length>0){ // Check whatever condition you have
return false;
}
else{
return true;
}
}