Reputation: 121
I have an application with routes guarded by an AuthGuard that implements CanActivate. Can activate checks to see if user is logged in and then checks if configuration variables are set before returning true or false. If the user is signed in but configuration variables have not been sent, AuthGuard makes an http call to retrieve configuration setup and returns true once the http call has been resolved without error (false otherwise).
The issue is that the Router is cancelling the navigation to the requested route before the configuration call has been resolved.
Below is the AuthGuard canActivate method:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
let authenticated = this.isAuthenticated();
if (authenticated) {
console.log("User authenticated, checking for configs...");
if (this.config.defined) {
console.log("Config defined!");
return true;
} else {
***** HERE ******
console.log("Config not defined, setting configs...");
this.authService.setConfig()
.take(1)
.subscribe(
config => {
// SET CONFIG VARIABLES
console.log("Config variables set");
// allow route access
return true;
},
err => {
console.error(err);
this.router.navigate(['/Login']);
return false;
}
);
this.router.navigate(['/Login']);
return false;
}
} else {
console.log("User not authenticated, back to login");
this.router.navigate(['/Login']);
return false;
}
}
So when I am logged in and the config variables are not set when I try to access a page (i.e. I'm in logical block denoted by **** HERE ****
), I see in the console:
Setting config...
NavigationCancel {id: 1, url: "/", reason: ""}
NavigationStart {id: 2, url: "/Login"}
RoutesRecognized {id: 2, url: "/Login", urlAfterRedirects: "/Login", state: RouterStateSnapshot}
NavigationEnd {id: 2, url: "/Login", urlAfterRedirects: "/Login"}
Config variables set
Before the AuthGuard config http call has a chance to resolve, the navigation is cancelled and the router redirects as if the AuthGuard had returned false. I would like to find a way to have AuthGuard return its result on resolution of the http call within.
Upvotes: 0
Views: 1544
Reputation: 121
If anyone else if having this problem, I solved the issue by replacing the contents of the else
block (starting with *****HERE******
) with the following:
return this.authService.setConfig()
.map(
config => {
// SET CONFIG VARIABLES
console.log("Config variables set");
// allow route access
return true;
})
.catch(err => {
console.error(err);
this.router.navigate(['/Login']);
return Observable.of(false);
});
Upvotes: -1