Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to provide routes dynamically at bootstrap?

How can I provide a service to a RouterModule so that I can dynamically inject routes based on some parameter?

Mind you, this parameter is also dynamic (it comes from an api call before bootstrapping).

I do realize that by using RouterModule.forRoot (which is a static function) I am quite constrained with injecting services.

like image 363
David Čamdžić Avatar asked Sep 20 '16 07:09

David Čamdžić


2 Answers

You need to provide the ROUTES token with a function that produces the routes configuration and takes that parameter. Also, you need to provide that parameter.

import {ROUTES} from '@angular/router/src/router_config_loader';
[...]
imports: [RouterModule.forRoot([])] // Empty on purpose
providers: [
  SomeParamForTheFunction,
  {provide: ROUTES, 
   multi: true, 
   useFactory: routesFunction, 
   deps: [SomeParamForTheFunction]},
]

How you provide that param is up to you. You could use another factory for it.

UPDATE: Since the routing configuration is now dynamic, you have to provide also an entryComponents property with all the components required for initial page load.

like image 197
Ruben Avatar answered Jan 04 '23 00:01

Ruben


In order to provide the entryComponents dynamically, you can make the following amendment to the code @Ruben provided:

import {ROUTES} from '@angular/router/src/router_config_loader';
import {ANALYZE_FOR_ENTRY_COMPONENTS} from '@angular/core';
[...]
imports: [RouterModule.forRoot([])] // Empty on purpose
providers: [
  SomeParamForTheFunction,
  {provide: ROUTES, 
    multi: true, 
    useFactory: routesFunction, 
    deps: [SomeParamForTheFunction]
  },
  {
    provide: ANALYZE_FOR_ENTRY_COMPONENTS,
    useValue: routes, // just write the original routes
    multi: true
  }
]

This way, you won't need to declare entryComponents once if they're declared at the module declarations.

like image 37
Burak Tasci Avatar answered Jan 03 '23 23:01

Burak Tasci