Luca Effe Federzoni
Luca Effe Federzoni

Reputation: 423

How to dynamically compose a route in angular?

Let's suppose I have a service that fetches an array of paths formatted in json like this:

[{
    "path": "routeName"
    "component": "MyComponent"
}]

Of coures "MyComponent" is retrieved as a string. Now I want translate this array into Routes for a routing-module. How can I convert "MyComponent" into the class MyComponent?

The purpose of this is to make my frontend unaware of what it is. To add new routes and components I just need to add a new entry to the file on the server and make it match the component name I create inside the angular app.

Upvotes: 3

Views: 5397

Answers (3)

Alex Ryltsov
Alex Ryltsov

Reputation: 2993

You can use ROUTES InjectionToken and instead of passing routes directly in the forRoot/forChild function of the RouterModule, just pass an empty array and instead provide the ROUTES token in the providers section. In that case the Angular router will automatically use the routes from the provided token.

For example,

@NgModule({
  imports: [
    ...
    RouterModule.forChild([])
  ],
  exports: [RouterModule],
  providers: [
    {
      provide: ROUTES,
      useFactory: (appSettings: AppSettings) => {
        const defaultTab: string = appSettings.APP_VERSION === APP_VERSIONS.NL ? 'tab1' : 'tab2';
        const routes: Routes = [
          {
            path: '',
            component: TabsPage,
            children: [
             ...
            ]
          },
          {
            path: '',
            redirectTo: defaultTab,
            pathMatch: 'full'
          }
        ];
        return routes;
      },
      deps: [
        APP_SETTINGS
      ],
      multi: true
    }
  ]
})
export class TabsPageRoutingModule {}

Upvotes: 0

Here is app module

export const routes: Route[] = [

];
@NgModule({
  declarations: [
    AppComponent,
    ErrorHandleComponent,
    FilterComponent,
    CreateComponent
  ],
  imports: [
    BrowserModule,
    RouterModule.forRoot(routes),
    // AppRoutingModule,
    HttpClientModule
  ],
  entryComponents: [
    CreateComponent,
    FilterComponent,
    ErrorHandleComponent
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Now make sure that you have the key value pair obj that returns component against key like:

import { CreateComponent } from '../create/create.component';
import { FilterComponent } from '../filter/filter.component';
import { ErrorHandleComponent } from '../error-handle/error-handle.component';

export const components = {
    'CreateComponent': CreateComponent,
    'FilterComponent': FilterComponent,
    'ErrorHandleComponent': ErrorHandleComponent,
};

Then put this code in app.component.ts file

  constructor(private api: ApiService, private router: Router) {

  }
  getRoute() {
    this.api.get_route().subscribe(res => {
      res.forEach(element => {
         // components key value pair obj
         element.component = components[element.component]; 
        routes.push(element);
      });
      this.rlist = routes;
      this.router.resetConfig(routes);
    });

Upvotes: 4

hugomac
hugomac

Reputation: 366

Step 1: Inject router into the app module

Step 2: You could change router.config whatever you want

@
NgModule({
declarations: [
  HomeComponent
  ...
],
imports: [
    RouterModule.forRoot([
        { path: '', redirectTo: 'home', pathMatch: 'full' },
        { path: 'home', component: HomeComponent },
        { path: '**', redirectTo: 'home' }
    ])
],
providers: []})


export class AppModule {
constructor(router: Router) {
    router.config.unshift({ path: 'new_path', component: NewComponent });
}}

Upvotes: 3

Related Questions