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
isLoaded
totrue
, 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.routeConfig
property. You can modify that instead of relying on the_loadedConfig
http://plnkr.co/edit/fBqrEpqafiVSB2Vvapzb?p=preview