question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItΒ collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Router - Routes Config transform hook

See original GitHub issue

πŸš€ feature request

Relevant Package

This feature request is for @angular/router

Description

Ability to transform/process routes when they are being registered (in order to be filtered/manipulated or so)

Describe the solution you’d like

@NgModule({
    imports: [RouterModule.forChild(ROUTES)],
    providers: [
        { provide: RoutesConfigHandler, useClass: AppRoutesConfigTransformer } // register in root
    ],
    exports: [RouterModule]
})
export class AppShellRoutingModule {

}

class AppRoutesConfigTransformer extends RoutesConfigHandler {

    constructor(
        appInfo: AppInfoService, // custom service
    )

    process(routes: Routes): Routes { // if it can take `Routes | Promise<Routes> | Observable<Routes>` as return even better but probably complicates things
        // perform custom logic on routes - validate data, set some data, filter or so...
        return routes;
    }

}

Describe alternatives you’ve considered

Tried to handle the more angular DI way, however with the router I had no luck. I tried even custom function for RouterModule.forChild (as how it is internally) but still nothing works.

@NgModule({
    imports: [RouterModule.forChild(ROUTES)],
    providers: [
       { provide: ROUTES, useFactory: validateProcessRoutes, deps: [AppInfoService] },
    ],
	exports: [RouterModule]
})
export class AppShellRoutingModule {

}

function validateProcessRoutes(routes: Routes) {
    // perform custom logic on routes - validate data, set some data, filter or so...
    return routes;
}

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:3
  • Comments:13 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
stephenlautiercommented, Oct 19, 2020

Oki so one of the examples i mentioned is to iterate through routes and add validation. Again the only problem we have is we are not able to use DI, so the requested feature is to enable DI pretty much, in this case a simple logger.

Validate the Routes has certain data e.g. RouteId in this case

This is how it currently is, and it works (update: doesnt work with AOT) , however in this example we cannot use our own logger (commented below)

export function appProcessRoutes(routes: Routes): Routes {
  return processRoutes(routes, routeIdCheck);
}

function processRoutes(routes: Routes, filterFn?: (route: Route) => boolean | undefined): Routes {
  return _.reduce(routes, (result, route) => {
    const isValid: boolean | undefined = filterFn?.(route);
    if (isValid === false) {
      return result;
    }
    result.push(route);

    if (route.children) {
      route.children = processRoutes(route.children, filterFn);
    }
    return result;
  }, [] as Routes);
}

function routeIdCheck(route: Route): boolean | undefined {
  const data = route.data as AppRouteData;
  if (!data.id) {
    const routeInfo = routeConfigDebugId(route); // code omitted
    // this.logger.error("routeIdCheck", "route has no 'id' specified", {route: routeInfo}); // need to use this
    console.error(`[routeIdCheck] route has no 'id' specified`, routeInfo);
    return false;
  }
}

Now in order to be able to use the logger we would need DI, and this is how we generally create it

constructor(
  loggerFactory: LoggingFactory
) {
  this.logger = loggerFactory.get("AppRoutesConfigTransform");
}

So again, the problem is that we are currently limited to only write code which doesn’t use any services.

Another issue is you need to apply this manually for each individual usage, like this:

@NgModule({
  imports: [RouterModule.forChild(appProcessRoutes(ROUTES))], // <-- like this
  exports: [RouterModule]
})
export class AppShellRoutingModule {

}

While with the other, you register the service once in root and thats it.

// copied from feature request above
@NgModule({
  imports: [RouterModule.forRoot(ROUTES)],
  providers: [
      { provide: RoutesConfigHandler, useClass: AppRoutesConfigTransformer }
  ],
  exports: [RouterModule]
})
export class AppRoutingModule {

}
1reaction
Airbladercommented, Oct 19, 2020

Thanks for taking the time to write this up, I appreciate it! I think understanding the use-case helps in finding solutions, be it existing ones or to think about a possible new feature. I’ll follow up with my thoughts on this below, but let’s see what the Angular team thinks about it. πŸ˜ƒ


Since this is about preventing misconfiguration during development, wouldn’t you rather want this to be a compile-time error rather than a runtime one, though? This could probably be covered in a test that scans the source for routing modules and then performs the checks (although admittedly I don’t know of specific tooling that makes writing such tests straight-forward).

As for a runtime version you could have a service which injects Router and then parses Router#config this way to log the errors. This wouldn’t disable those routes, though this could then still be achieved by keeping that validation result and accessing it from a guard.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How React Hooks can replace React Router - LogRocket Blog
Looking for an alternative form of routing in your React projects? Read more to find out how React Hooks can replace React Router....
Read more >
Chapter: Configuring Static Routing - Cisco
This chapter describes how to configure static routing on the switch. This chapter includes the following sections: β€’ Information About Static Routing.
Read more >
Specifying a Route's Model - Ember Guides
In the model hook for routes with dynamic segments, it's your job to turn the ID (something like 47 or post-slug ) into...
Read more >
How To Handle Routing in React Apps with React Router
In this tutorial, you'll install and configure React Router, build a set of routes, and connect to them using the <Link> component.
Read more >
Common Routing Tasks - Angular
To set up a redirect, configure a route with the path you want to redirect from, the component you want to redirect to,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found