I have a CanActivate guard service that has been working fine, until a new requirement came along. The original code was something like this:
canActivate(
route: ActivatedRoutesnapshot,
state: RouterStateSnapshot
): boolean | UrlTree | Observable<boolean> | Promise<boolean | UrlTree> {
if (!this.isUserLoggedIn()) {
... force login, return false
} else if (this.shouldDoMoreChecks()) {
return doMoreChecks(); // returns boolean | UrlTree | Promise<boolean | UrlTree>
} else {
return this.authGuardService.canActivate(); // returns boolean | Promise<boolean> | Observable<boolean>
}
Now we have a new requirement that we need to subscribe to a selector and depending on the value returned, add additional checks in the second branch. Since this is (obviously) asynchronous, my idea was that I should put the subscription in the second branch like so:
if (!this.isUserLoggedIn()) {
... force login, return false
} else {
return this.store$.select(mySelector).pipe(
take(1),
map(response => {
if (this.shouldDoMoreChecks(response)) {
return doMoreChecks(); // returns boolean | UrlTree | Promise<boolean | UrlTree>
} else {
return this.authGuardService.canActivate(); // returns boolean | Promise<boolean> | Observable<boolean>
}
}
}); // returns Observable<boolean | UrlTree | Promise<boolean | UrlTree>>
}
I'm at a loss as to how to "unwrap" the Observable returned from the map() function so the return isn't
Observable<boolean | UrlTree | Promise<boolean | UrlTree>>
but is instead
boolean | UrlTree | Promise<boolean | UrlTree>
I'm sure there's something blindingly obvious, but I'm not seeing it.
EDIT So, I had tried using switchMap before but had given up because of errors. Now I realize that I just needed to fix the return types of the various functions. I've implemented switchMap and am testing, so far so good. One thing I ended up having to do was
return of(Boolean(this.guardService.canActivate(route, state).valueOf()));
because it could possibly return boolean, which switchMap did not approve of. It seems inelegant, but I'm not sure there's a different way to handle it?