I'm trying to implement this CanDeactivate Route Guard using kendo-ui angular dialog instead of the window.confirm,
It works fine with window.confirm but with kendo-ui dialog only the second time I execute the dialog. The first time the method this.confirmCanExitDialog()
returns false even if I click Yes and the second time I execute the dialog by trying to navigate somewhere else, it returns true.
The problem I have is that this line return this._canExitResult$$.value;
executes before the dialog.result even if I make the method return an Observable<boolean>
, the result is always false (initial value). Please help.
public canExit(): boolean {
return this.form.dirty ? this.confirmCanExitDialog() : true;
}
private confirmCanExitDialog(): boolean {
const dialogRef = this.dialogService.open({
content: ConfirmDialogComponent,
});
const confirmDialog = dialogRef.content.instance as ConfirmDialogComponent;
confirmDialog.message = 'Confirmation.CanExit';
dialogRef.result.subscribe((result: DialogCloseResult) => {
if (result === 'Yes') {
this._canExitResult$$.next(true);
}
if (result === 'No') {
this._canExitResult$$.next(false);
}
});
return this._canExitResult$$.value;
}
window.confirm
is a blocking call and this is why this code works:
public canExit(): boolean {
return this.form.dirty ? window.confirm() : true;
}
If you want to use non-blocking dialog like kendo, then you have to return Observable
/Promise
:
canDeactivate(component: any, currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot, nextState: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.form.dirty ? this.confirmCanExitDialog() : of(true);
}
private confirmCanExitDialog(): Observable<boolean> {
const dialogRef = this.dialogService.open({
content: ConfirmDialogComponent,
});
const confirmDialog = dialogRef.content.instance as ConfirmDialogComponent;
confirmDialog.message = 'Confirmation.CanExit';
return dialogRef.result.pipe(map(x => x === 'Yes'));
}