6

I have a main module and some submodules. And I want to specify some not trivial routing between them.

I'd prefer defining the routes of a submodule within the submodule. E.g.:

@NgModule({
    imports: [
        /*...*/
        RouterModule.forChild([
            { path: 'country', redirectTo: 'country/list' },
            { path: 'country/list', component: CountryListComponent },
            { path: 'country/create', component: CountryCreateComponent },
            /*...*/
        ])
    ],
    declarations: [/*...*/],
    exports: [
        RouterModule,
    ],
})
export class CountryModule {}

I want to import this module with its own internal routing, but I want to make its whole routing prefixed.

const appRoutes = [
    { path: '', component: HomeComponent },
    /*... (basic routes)*/
];

@NgModule({
    imports: [
        /*...*/
        RouterModule.forRoot(appRoutes),
        CountryModule, // <- how to make its routing prefixed??
    ],
    declarations: [
        /*...*/
        AppComponent,
    ],
    bootstrap: [ AppComponent ]
})
export class AppModule {}

This settings creates the following routes: /country, /country/list, etc., but I want to make them prefixed like this:

  • /settings/country
  • /settings/country/list
  • /settings/country/create

There are other modules that I want to access via another routing, e.g. a CityModule under /otherstuff/city/create and /otherstuff/city/list`.

My questions:

  1. Is it possible to import a module with its own routing and make its routes prefixed?
  2. Furthermore: Is there a way to make links between 2 submodules agnostically of their final (prefixed) routes?

UPDATE

The accepted answer is the best way to do it: create the routes in the module, register them externally. Thus you can modify the routes, e.g. prefix them (this is what I wanted), you can define guards, override or filter them, etc.

1

2 Answers 2

10

Playing with this Routing stuff I just found a clean way I would like to share, to handle the routes of submodules with no headaches and love Angular even more. Taking the OP case as an example, I propose you to study the following code:

Add a utility function to your CountryModule submodule, to load it dynamically from the Router and avoid a compiler warning about replacing the arrow function with a reference to an exported function:

@NgModule({
  imports: [
    ...
    RouterModule.forChild([
      { path: 'country', pathMatch: 'full', redirectTo: 'list' },
      { path: 'country/list', component: CountryListComponent },
      { path: 'country/create', component: CountryCreateComponent },
    ])
  ],
  declarations: [ ... ],
  exports: [
    RouterModule,
  ],
})
export class CountryModule {}

export function CountryEntrypoint() {
  return CountryModule;
}

Now you can import that Entrypoint into your parent module where you want to place the routes:

@NgModule({
  imports: [
    ...
    RouterModule.forRoot([
      { path: '', pathMatch: 'full', component: HomeComponent },
      { path: 'settings', loadChildren: CountryEntrypoint }
    ]),
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule {}

And there you go! You can now reach your submodule components with settings/country/list and settings/country/create.

WARNING

Be careful to not import the CountryModule into your parent module's @NgModule, because it will override the routes outside the settings path. Let the router do the job.

Enjoy!

Sign up to request clarification or add additional context in comments.

6 Comments

This should be the accepted answer. Note you don't need to export an "entrypoint" you could just do loadChildren: () => CountryModule.
@MichaelPetito we could, but there is an error/warning with angular/cli that complains about using lambdas and suggest to replace them with exported functions ;)
Probably you should emphasize more, your warning 'not to import into parent module'. You saved me from scratching my head and running around in circles.
@fossil bold CAPS was not enough? hehe glad I saved your time
the lazy-loading is preserved?
|
6

in your appRoutes add child route like

const appRoutes = [
    { path: '', component: HomeComponent },
    {
    path: 'settings',
    component: CountryComponent,
    canActivate: [AuthGuard],
    children: COUNTRY_ROUTES
  },
];

Create a separate routes file

export const COUNTRY_ROUTES:Routes = [
  { path: 'country', redirectTo: 'country/list' },
  { path: 'country/list', component: CountryListComponent },
  { path: 'country/create', component: CountryCreateComponent },

];

In CountryComponent.html

<router-outlet></router-outlet>

2 Comments

Just to clarify: There is no way to change the routing of a module once it's imported into the module?
@Gábor Imre, you cannot.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.