I have routes setup like so:
export const APP_ROUTES: Routes = [
{
path: '',
resolve: {
user: CurrentUserResolver
},
children: [
{
path: ':sectionKey',
canActivate: [SectionAccessGuard],
children: [
{
path: 'dashboard',
component: DashboardComponent
}
]
}
]
}
]
Where the parent route will retrieve the user via a HTTP call, and I'd like my sub-route :sectionKey
to only be activated if the current user has access to it. The issue is, it appears my canActivate SectionAccessGuard
is called prior to the snapshot being fully populated:
@Injectable()
export default class SectionAccessGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
console.log(route.data);
console.log(route);
return true;
}
}
In the console, the first entry will have nothing; however, the 2nd entry will eventually have the user
field populated.
I know the canActivate
method can return an Observable<boolean>
as well, but I don't see any hooks on how to wait until the resolve completes.
What am I missing here? I feel like this should be pretty straight forward. I'm currently using angular v4.0.0-rc.2
It's been about 8 months since I posted this so I'll give an update on where we ended up:
Storing data in the router through resolves started to become very awkward depending on where the component was (this.route.parent.parent.parent.data.user
), so we're no longer using resolves, and instead using NgRx to store that kind of information.
Our guards then are in charge of triggering the fetching of the data, as well as waiting until it's complete. Something like this:
@Injectable()
export class AuthenticationGuard implements CanActivate {
constructor(private router: Router, private store: Store<ApplicationState>) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
this.store.dispatch(new AuthenticateAction());
return this.store
.select('auth')
.filter((s) => !!s && !s.authenticating)
.map((s) => s.authenticated)
.take(1);
}
}
Where there are a couple flags in the state (authenticating and authenticated) that tell the guard where we're at in the process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With