'CanActivate guards on child routes run before parent Resolve finish
I'm trying to resolve data before navigating to children routes as i have to use that data in children guard. The issue is parent resolver, resolves data after the child guard is fired. Resolver takes long time to resolve data
// app.module.ts
const appRoutes: Routes = [
{ path: 'login', component: LoginComponent },
{
path: '',
component: SiteLayoutComponent,
children: [
{ path: '', redirectTo: 'warehouse', pathMatch: 'full' },
{
path: 'warehouse',
loadChildren: './warehouse/warehouse.module#WarehouseModule'
// loadChildren: () => WarehouseModule
}
],
canActivate: [AuthGuard],
resolve: {
Site: SiteResolver // should be resolved before the guard is invoked.
}
},
{ path: '**', component: PageNotFoundComponent }
];
// warehouse.module.ts
const appRoutes: Routes = [
{ path: '', redirectTo: 'cash', pathMatch: 'full' },
{ path: 'cash', component: CashComponent, canActivate: [RouteGuard] // should be invoked after the parent resolver resloves th data }
];
Here, the parent resolver i.e. SiteResolver resolves after the child guard i.e. RouteGuard is invoked. What i want is SiteResolver to resolve data first and then RouteGuard should fire, how can i achieve that ?
Solution 1:[1]
I am not sure if this is the correct method. But after going through a lot of angular issues , i found a workaround.
Instead of resolve , use canActivate to fetch data and store the data in the service. Below is the code snippet for the same
@Injectable()
export class FetchUserData implements CanActivate {
constructor(
private userService: UserService,
private httpClient: HttpClient
) {}
public modalRef: BsModalRef;
canActivate() {
return this.httpClient
.get("some/api/route")
.map(e => {
if (e) {
this.userService.setUserDetails(e);
return true;
}
return true;
})
.catch(() => {
return Observable.of(false);
});
}
}
It worked for me well. You will have no problem in refreshing the child route.
Solution 2:[2]
My solution to this situation was to wrap the entire application in a lazy module and hang canLoad on it
{
path: '',
children: [
{
path: '',
canLoad: [PortalResolver],
loadChildren: () => import('./portal/portal.module').then(m => m.PortalModule),
}
],
},
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Renil Babu |
Solution 2 | ????? ????? |