Angular 11: Make canDeactivate observable wait for nested function

438 views Asked by At

I'm trying to replace my browser alert with a custom one using Material dialog. If the user tries to navigate away from the form with unsaved changes, the custom alert shows. But I need to wait (pause the function) until the user clicks an option to return the value.

discardChangesAlertResult: boolean;

canDeactivate(): Observable<boolean> | Promise<boolean> | boolean {
    if (this.hasBeenEdited) {

        const dialogRef = this.dialog.open(DiscardChangesComponent, {panelClass: 'alert'});
        
        dialogRef.afterClosed().subscribe(result => {
            if (this.discardChangesService.discardChangesAlert) {
                this.hasBeenEdited = false;
                this.discardChangesAlertResult = true;
            } else {
                this.discardChangesAlertResult = false;
            } 
        });

        return this.discardChangesAlertResult; // I need this line to wait for user input
    } else {
        return true;
    }
}
1

There are 1 answers

0
Artur Kulik On BEST ANSWER

you have to return Observable for that.

canDeactivate(): Observable<boolean> | Promise<boolean> | boolean {
    if (!this.hasBeenEdited) {
        return true;
    }
    return this.dialog
        .open(DiscardChangesComponent, {panelClass: 'alert'})
        .afterClosed()
        .pipe(map(result => {
            if (this.discardChangesService.discardChangesAlert) {
                this.hasBeenEdited = false;
            }
            return !!this.discardChangesService.discardChangesAlert;
        });
}