4

I have a function inside the component to check if I can leave the route by evaluating a form status. If the status matches to a contidition which I need to ask to leave the route, it shows up a dialog to confirm or cancel. I call this function inside my canDeactivate service, but it triggers the response before waiting for the dialog confirmation.

I've already put a console.log inside the canDeactivate service with the component's function. When a confirmation is not required, it shows true as expected. But on the other hand, when a confirmation is required, it shows undefined before the dialog box appears.

canDeactivateService.ts

@Injectable()
export class ProdutosDeactivateGuard implements CanDeactivate<ExampleComponent> {

  canDeactivate(
      component: ExampleComponent,
      route: ActivatedRouteSnapshot,
      state: RouterStateSnapshot
    ): boolean {
      return component.checkStatus();
  }
}

example-component.ts

checkStatus() {
    if (!this.form.pristine && this.form.touched) {
      const dialogRef = this.dialog.open(DeactivateDialogComponent);
      dialogRef.afterClosed().subscribe(result => {
        if (result === 'true') {
          return true;
        } else {
          return false;
        }
      });
    } else {
      return true;
    }
  }
}

I'd like the service to wait for the confirmation. How could I do this?

Diego de Lima
  • 471
  • 2
  • 7
  • 15
  • Does `component.checkStatus()` return value properly inside guard? – MonkeyScript Oct 16 '19 at 14:52
  • @Arcteezy it's the issue. When the dialog is not required, it returns properly. But when the dialog is required, the guard trigger the return before wait the response of the function. – Diego de Lima Oct 16 '19 at 15:28

1 Answers1

7

Have you tried returning an observable? as I see in your code afterClosed() returns one.

For example:

@Injectable() export class ProdutosDeactivateGuard implements CanDeactivate {

canDeactivate(
      component: ExampleComponent,
      route: ActivatedRouteSnapshot,
      state: RouterStateSnapshot
    ): Observable<boolean> {
      return component.checkStatus();
  }
}

checkStatus() {
    if (!this.form.pristine && this.form.touched) {
      const dialogRef = this.dialog.open(DeactivateDialogComponent);
      return dialogRef.afterClosed().pipe(map(result => {
        return result === 'true';
      }));
    } else {
      return of(true);
    }
  }
}
Agustin Seifert
  • 1,938
  • 1
  • 16
  • 29
  • 1
    thanks for your support! It's working fine now! I will look at some material about Observable. I was trying to use that before but I still don't understand it very well. – Diego de Lima Oct 16 '19 at 16:27