问题
I have an AuthGuard in which I want to use a login material2 dialog with it. So before canActivate returns, the login dialog is shown and if the login is successful then the dialog returns true so then canActivate returns true as well. If the login is not successful, then the dialog does not return anything and tries again.
I have already implemented the dialog in a component and its working fine, I'm looking for help on how to integrate it with the canActivate guard.
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService,
private dialog: MatDialog,
private router: Router) {}
successfulLogin: boolean;
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
// Open the Dialog
let dialogRef = this.dialog.open(LoginDialog, {
width: '450px',
data: { success: this.successfulLogin }
});
// NEED HELP HERE, UNSURE HOW TO RETURN
return dialogRef.afterClosed().subscribe(result =>{
return result;
})
}
}
The result from the subscribe is returning true but I am unsure about the logic on how to return from canActivate properly. The code above gives the following error statement.
Type 'Subscription' is not assignable to type 'boolean | Observable | Promise'. Type 'Subscription' is not assignable to type 'Promise'. Property 'then' is missing in type 'Subscription'.
回答1:
Use the toPromise method instead
return dialogRef.afterClosed().toPromise().then(result =>{
return result ? true : false;
});
回答2:
Actually, there's no reason to use a Promise there, if you don't want to.
The problem you're facing is that you're actually returning your Subscription (i.e.: the result of calling .subscribe(...) on your Observable) instead of the Observable itself!
Simply use:
return dialogRef.afterClosed();
Or better yet, if result isn't actually a boolean:
return dialogRef.afterClosed().pipe(result => !!result);
来源:https://stackoverflow.com/questions/48955831/angular-canactivate-with-login-dialog