16

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?

Spurious
  • 1,903
  • 5
  • 27
  • 53

4 Answers4

19

Have you tried loading it like this:

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

You can find a lot more details here.

Emin Laletovic
  • 4,084
  • 1
  • 13
  • 22
  • 1
    Thanks, I will have a read through this and try your solution tomorrow. Will keep you posted and upvote if it works. – Spurious Aug 01 '17 at 20:38
  • This will disable the lazy loading feature. – Ben Dec 05 '18 at 13:17
  • 1
    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 – Mickey Sly Dec 11 '18 at 19:11
  • 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](https://github.com/angular/angular-cli/issues/5460#issuecomment-34193153) [Stack-Overflow](https://stackoverflow.com/questions/42846582/exception-runtime-compiler-is-not-loaded) – MiKr13 Jan 04 '21 at 10:52
6

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

yurzui
  • 205,937
  • 32
  • 433
  • 399
  • It would make the second routing module obsolete - something I explicitly want to avoid. – Spurious Aug 01 '17 at 20:38
  • Thanks for your edit but the imports already exist and it does not work. – Spurious Aug 02 '17 at 04:58
  • @Spurious I think you forgot to change `{ path: '', component: SubComponent` to { `path: 'sub', component: SubComponent` in `sub-routing.module.ts` – yurzui Aug 02 '17 at 05:10
  • 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. – Chris Haines Jan 23 '19 at 10:56
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 },
];
HungNM2
  • 3,101
  • 1
  • 30
  • 21
-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.