Skip to content

Consider populating the router.config鈥hildren array the same for static and lazy loaded routes聽#40010

Open

Description

@epaitz

馃殌 feature request

Relevant Package

This feature request is for @angular/router

Description

Consider populating the router.config鈥hildren 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鈥檚 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鈥檚 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鈥檚 a long shot, but I wanted to suggest the general idea.

Thanks,
Eric

Activity

  1. modified the milestone: needsTriage on Dec 8, 2020
  2. added
    featureLabel used to distinguish feature request from other issues
    on Dec 8, 2020
  3. modified the milestones: needsTriage, Backlog on Dec 8, 2020
  4. angular-robot commented on Jun 4, 2021

    @angular-robot
    Contributor

    Just a heads up that we kicked off a community voting process for your feature request. There are 20 days until the voting process ends.

    Find more details about Angular's feature request process in our documentation.

  5. angular-robot commented on Jun 25, 2021

    @angular-robot
    Contributor

    Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage.

    We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package.

    You can find more details about the feature request process in our documentation.

  6. SchnWalter commented on Jul 2, 2021

    @SchnWalter
    Contributor

    The router config changes as you load new lazy-loaded modules and it contains can contain wildcard routes, routes with parameters, URL matchers, etc., on a complex application generating a menu from the routing system is not really feasible.

    I would suggest that you go the other way, and generate your menu and register routes from a single configuration file; you just need to make sure that you don't use dynamic ES module imports; just stick all LoadChildrenCallback instances in there.

    You can then provide that configuration via DI, to use it in your navigation menu, and maybe in some sort a route registry (a feature registry?) to register routes during the bootstrap process, see the ExtraOptions.initialNavigation router option and Router.initialNavigation() method.

  7. added
    feature: under considerationFeature request for which voting has completed and the request is now under consideration
    and removed on Oct 3, 2022
  8. vickyRathee commented on Nov 20, 2022

    @vickyRathee

    @SchnWalter Adding this will help a lot, as the complex application can also benefit by using the data{} to specify if the menu should be displayed or not { menu: true/false }.

    Also this helps us to centralize the routing, menu and permissions.

    For example, this is how we do in dayschedule.com

    Routing table with menu, permission etc.
    image

    Then an array to get menu and use the *ngFor to display menu. Also the permsCheck() to show hide based on permissions, and authGurad to prevent the access.

    image

    So having the suggested feature will make it lot easier to do the same for children pages as well. As we would be able to get the children to create an array with Main > Sub menus automatically added as a new route added or changes.

  9. muuvmuuv commented on May 8, 2025

    @muuvmuuv

    Hey, I build a lib where you can define menu on any route: https://github.com/muuvmuuv/angular-router-menus . @vickyRathee maybe this is something for you?

    It does use internal and private api's atm, see my ticket #61192

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: routerfeatureLabel used to distinguish feature request from other issuesfeature: under considerationFeature request for which voting has completed and the request is now under considerationrouter: lazy loading

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions