Issue 1:
I'm submitting a ... (check one with "x")

[ ] bug report => search github for a similar issue or PR before submitting
[X] 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

When accessing modules lazily, RouteConfigLoadEnd gets fired once the factory gets loaded, but before routes are loaded and assigned to route._loadedConfig.

Expected behavior

RouteConfigLoadEnd should be fired after _loadedConfig is assigned, or return routes as a parameter if it's fired from RouterConfigLoader.

Change proposal:

return map.call(moduleFactory$, (factory: NgModuleFactory<any>) => {
const module = factory.create(parentInjector);
const routes = flatten(module.injector.get(ROUTES));

if (this.onLoadEndListener) {
this.onLoadEndListener(route, routes);
}

return new LoadedRouterConfig(routes, module);
});

What is the motivation / use case for changing the behavior?

Most common use case of RouteConfigLoadEnd is to react once lazy loaded routes are loaded. In localize-router we can use this information for routes localization. However if even is fired before routes are de facto available in _loadedConfig and/or it doesn't provide this information it makes the entire event unusable as it's not that different from RouteConfigLoadStart.

Issue is already mentioned here: #14036

Angular version: 4.0.X

Browser: all

Language: all

Issue 2:
🚀 feature request

Relevant Package

This feature request is for @angular/router

Description

Consider populating the router.config…children array the same for static and lazy loaded routes.

Describe the solution you'd like

Some developers including myself like to create navigation elements, say for a header component, directly from the router.confg. Everything is already populated in the router config (including custom data and access via a RouteGuard). When using static routes I would normally do something like the following.

this.items = this.router.config
.find((route: Route) => {
return route.path === this.routePath
})
?.children
.filter((route: Route) => {
return route.data != null
})
.map((route: Route, index) => {
return {
path: "/" + this.routePath + "/" + route.path,
icon: route.data.icon,
label: route.data.label
}
});

The code above simply creates an object array called items for the children of a specific route. I am not showing all the detail but just focusing on the children array because these are static routes. The object returned can be anything the developer needs.

Now when using lazy loaded routes the children array is not available because the routing data is stored in lazy loaded modules that have not been loaded yet. Several people have tried to use the private _loadedConfig property on a route but it gets ugly and you end up with something like this.

this.buttons = (this.router.config
.find((route: Route) => {
return route.path === this.routePath
}) as any)
?._loadedConfig
?.routes[0]
?.children
.filter((route: Route) => {
return route.data != null
})
.map((route: Route, index: number) => {
return {
path: "/" + this.routePath + "/" + route.path,
icon: route.data.icon,
label: route.data.label,
}
})

While this works its not ideal. The obvious issue is that the private _loadedConfig is subject to change without warning in the future because its not part of the public API and this object is not available until some point in the lifecycle that I have not been able to determine yet.

Now the data that is eventually available in the _loadedConfig is exactly what developers are interested in (path, data, etc.) and it seems to be available even before the lazy modules are loaded. Given this would it be possible to present this information using the normal children array regardless if it’s a static route or a lazy loaded route? In most scenarios developers only care to have access to the route children and its less important that it’s from a static route vs. a lazy loaded route. A Boolean or enumeration could be added that would let the developer know the route static vs lazy if that is important.

This would mean any code designed to work with the router, config, and children would work with static or lazy loaded routes. The project could start with standard static routes and then later be reconfigured to use lazy routes and any code already in place that leverages the router config would continue to work.

One additional thought would be at webpack/compile time Angular would have access to all the routes regardless if they are static or lazy. Maybe some metadata can be derived from this and used to populate the routes children information at runtime.

I know it’s a long shot, but I wanted to suggest the general idea.

Thanks,

Eric