19

I want to have multiple routing modules in order to keep my application clean and easy to read. I currently use lazy loading for the SubComponent but I don't want to do this. So I am looking for a way to change this. Anyways, here is the currently working code.

I have the following two routing files.

app-routing.module.ts:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'sub', loadChildren: './sub/sub.module#SubModule' }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})

sub-routing.module.ts:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  { path: '', component: SubComponent, children: [
    { path: 'new', component: SubEditComponent }
  ] },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})

It works fine this way but I don't want to apply lazy loading to this SubComponent. So, ideally I want to change the app-routing.module.ts to this:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'sub', component: SubComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})

This will not work and result in the following error:

ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'sub/new'
Error: Cannot match any routes. URL Segment: 'sub/new'

The SubComponent will grow substantially in size and I don't want to apply lazy loading for my own reasons. So in any event, is there a way to use multiple routing files while avoiding lazy loading?

4 Answers 4

25

Have you tried loading it like this:

{ path: 'sub', loadChildren: () => SubModule }

You can find a lot more details here.

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

4 Comments

Thanks, I will have a read through this and try your solution tomorrow. Will keep you posted and upvote if it works.
This will disable the lazy loading feature.
It works on recompile but i get syntax errors when building or re-running the app. How do you get past this error: ERROR in Cannot read property 'loadChildren' of undefined
Please note, this solution can cause issues in a Production build. The error will be: ERROR: Runtime Compiler is Not Loaded or something like that. reference: Github Stack-Overflow
7

You forgot to declare child route to new

const routes: Routes = [
  { path: '', component: HomeComponent },
  { 
    path: 'sub', 
    component: SubComponent,
    children: [
      { path: 'new', component: SubEditComponent }
    ] 
  }
];

if you want to keep the second routing module then

sub-routing.module.ts

const routes: Routes = [
  { path: 'sub', component: SubComponent, children: [
    { path: 'new', component: SubEditComponent }
  ] },
];

sub.module.ts

@NgModule({
  ...
  imports: [
   ...
   SubRoutingModule,

app.module.ts

@NgModule({

  imports: [
    ...,
    AppRoutingModule,
    SubModule

Plunker Example

4 Comments

It would make the second routing module obsolete - something I explicitly want to avoid.
Thanks for your edit but the imports already exist and it does not work.
@Spurious I think you forgot to change { path: '', component: SubComponent to { path: 'sub', component: SubComponent in sub-routing.module.ts
This is the correct answer that works for prod (AOT) builds. To summarise, import the submodule into AppModule, and put the routes only in the submodule. No need for any route entries in AppModule for the submodule routes.
0

app.module.ts

 @NgModule({
    
      imports: [
        ...,
       SubModule,   /* subModule with routing, the order is very important */ 
       AppRoutingModule,  // put it at the end
      ]
}

the order of routing Modules is very important.

AppRoutingModule.ts

const routes: Routes = [
  // filter path '**' will prevent routing to the subModule
  { path: '**', component: PageNotFoundComponent },
];

Comments

-3

You can use an arrow function as eminlala said, but it won't work if you run a prod build.

{ path: 'sub', loadChildren: () => SubModule }

So, in order to make it work in a prod build, you need to create an export function as follows.

import SubModule from 'path-to-sub-module';

export function loadSubModule() {
  return SubModule;
}

export const SUB_MODULE_ROUTING = {
  path: 'sub',
  loadChildren: loadSubModule,
};

I use to create a file with this conf and import it to the AppRoutingModule, but you can write it inside AppRoutingModule.

I hope it helps.

1 Comment

The suggested solution makes no difference whatsoever to prod builds.

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.