angular: Router.resetConfig doesn't make child routes navigable
I’m submitting a … (check one with “x”)
[ x ] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
Calling router.resetConfig(newConfig) makes new routes available if they are top-level routes. If the new routes are children of an existing route, they are not navigable, despite being visible in router.config.
Expected behavior
Calling router.resetConfig(newConfig) should make all new routes available, including children of an existing route.
Reproduction of the problem
From within a component, call this.router.resetConfig() with an updated route config – the new routes should be children of an existing route. E.g:
let routerConfig = this.router['config'];
routerConfig[0]._loadedConfig.routes[0].children.push({
path: `lazy-loaded-module-1`,
loadChildren: `/lazy-loaded-module-1/app.module.js#ModuleOne`
});
this.router.resetConfig(routerConfig);
(I understand that the above is not strictly standard but conceptually, should still work.)
What is the motivation / use case for changing the behavior?
My Application needs to download additional modules after logging in. These should all be registered as child routes of an ‘/app’ route.
/login/app/app/home/app/lazy-loaded-module-1 // Added at runtime/app/lazy-loaded-module-2 // Added at runtime
Please tell us about your environment:
- Angular version: 2.0.0-rc.5
- Browser: all (Tested in Chrome 52)
- Language: TypeScript 1.8.9
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 5
- Comments: 19 (5 by maintainers)
@m-sawicki: Ah, I think I know the problem that you’ve encountered. The route guard needs to be attached to a route, but if the route doesn’t exist yet, it’s impossible to load. In this case, you must have a route to handle the request – indeed, this may be a wildcard (
**) route.To adjust the earlier example, after you set
isLoadedtotrue, instead of callingresolve(true), you’ll actually callresolve(false). This will stop the wildcard route from loading. Instead, you’ll retry the original request.I used @Jonymul 's code but I had a small problem - my browser history had a useless entry with the URL of the root of my app. That means go to the actual previous page I had to click Back twice.
I used
this.router.navigateByUrl(state.url, { replaceUrl: true });instead, where{ replaceUrl: true }is the fix for this.@m-sawicki
canActivate()doesn’t have to synchronously return a boolean. Instead, you can return a Promise or an Observable. Below, the Promise always resolves withtrue, but only after the routes have been added. The HTTP request should probably handle the error case, but I’ll leave that to you.Hope this helps.
@Jonymul there is also a slightly cleaner way to modify the routeConfig inside a lazy loaded module. Each component is provided its route config with the
ActivatedRoute.routeConfigproperty. You can modify that instead of relying on the_loadedConfighttp://plnkr.co/edit/fBqrEpqafiVSB2Vvapzb?p=preview