49

I'm trying to implement lazy routing into my app.

I have a very big project and when it was at router-deprecated I used AsyncRoute, but now it was removed.

So I tried to implement newest lazy loading, but I got an issue RangeError: Maximum call stack size exceeded What I'm doing wrong? I did all code like in instructions.

Take a look please

EncountersModule

    import { NgModule } from '@angular/core';
    // import { CommonModule } from '@angular/common';
    /* ---------------  !System modules  --------------- */

    import { SharedModule } from 'sharedModule';   //There is  a lot of shared components/directives/pipes (over 60) and it re-exports CommonModule so I can't avoid it
    /* ---------------  !App outer modules  --------------- */


    import { EncountersComponent } from './encounters.component';
    // import { PassCodeComponent } from '../../shared/components/passcode/passcode.component';


    @NgModule({
      imports: [ SharedModule ],
      declarations: [ EncountersComponent],
      exports: [ EncountersComponent ],
    })


    export class EncountersModule {  }

Here is my app.routing.module

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


import { ImagingComponent }      from '../modules/index';
import { DashboardComponent }      from '../modules/index';
import { PrescriptionNoticesComponent }      from '../modules/index';
// import { EncountersComponent } from "../modules/encounters/encounters.component";
import { ScheduleComponent } from "../modules/schedule/schedule.component";
import { AdminComponent } from '../modules/index';




@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: '',
        component: DashboardComponent,
        data: { label: 'Dashboard' }
      },
      {
        path: 'encounters',
        // component: EncountersComponent,
        loadChildren: 'production/modules/encounters/encounters.module#EncountersModule',
        data: { label: 'Encounters' }
      },
      {
        path: 'admin',
        component: AdminComponent,
        data: { label: 'Admin' }
      }
    ])
  ],
  exports: [
    RouterModule
  ]
})
export class AppRoutingModule {}




// const appRoutes: Routes = [
//   {
//     path: 'imaging',
//     component: ImagingComponent,
//     data: { label: 'Imaging' }
//   },
//   {
//     path: '',
//     component: DashboardComponent,
//     data: { label: 'Dashboard' }
//   },
//   {
//     path: 'prescription_notices',
//     component: PrescriptionNoticesComponent,
//     data: { label: 'Prescription Notices' }
//   },
//   {
//     path: 'encounters',
//     component: EncountersComponent,
//     data: { label: 'Encounters' }
//   },
//   {
//     path: 'schedule',
//     component: ScheduleComponent,
//     data: { label: 'Schedule' }
//   },
//   {
//     path: 'admin',
//     component: AdminComponent,
//     data: { label: 'Admin' }
//   }
// ];
//
// export const appRoutingProviders: any[] = [
//
// ];
//
// export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
4
  • 2
    probably it because I didn't have any routing for my encounters.module Commented Oct 19, 2016 at 14:01
  • Possibly try removing comments. When I updated my router to current in the application I was working on I commented a bunch of stuff out from the old router because I didn't want to lose it. After removing comments some of the strange errors went away. Although I had all of my comments at the top of my code so I am not sure if that applies here. Commented Oct 19, 2016 at 19:20
  • Thanks Frank for your help! Commented Oct 20, 2016 at 11:37
  • Glad that worked! I posted the answer so people can find it easier. That same problem had me stumped for almost a whole day when I was updating. Commented Oct 20, 2016 at 18:03

8 Answers 8

93

loadChildren needs to reference module with routing

By assigning a value to loadChildren property inside a route, you have to reference a module, which has a routing system implemented. In other words reference only a module that imports RoutingModule and configures it with forChild(routes) method.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
// import { CommonModule } from '@angular/common';
/* ---------------  !System modules  --------------- */

import { SharedModule } from 'sharedModule';   //There is  a lot of shared components/directives/pipes (over 60) and it re-exports CommonModule so I can't avoid it
/* ---------------  !App outer modules  --------------- */


import { EncountersComponent } from './encounters.component';
// import { PassCodeComponent } from '../../shared/components/passcode/passcode.component';

export const encountersModuleRoutes: Routes = [
  /* configure routes here */
];


@NgModule({
  imports: [ SharedModule, RouterModule.forChild(encountersModuleRoutes) ],
  declarations: [ EncountersComponent],
  exports: [ EncountersComponent ],
})


export class EncountersModule {  }
Sign up to request clarification or add additional context in comments.

5 Comments

go f'n figure!!
God bless you. Have a blissful life my friend. I was trying to find the error from 1 hour almost and you saved my n numbers of hours :D
Yep, this is definitely a module import/loading issue, also be careful with order of imports in the referenced module, I had random and annoying issues with the placement of the CommonModule.
thanks, i got this error when i accidentally remove the import for my routing module. had no idea what it was about :)
I second the comment by @VikasBansat. God Bless you for figuring this out...I've been seeking an answer to this one for days!
17

I am not sure because it is not explicitly mentioned in the documentation (2.4.2), but from the examples in the "Angular Modules" and "Routing & Navigation" guides, I have induced the following pattern:

  • The lazy module should have his own routing module.
  • The routes array defined in the "lazy-routing.module" should have a single element; the path property of that element should be an empty string; the component property should be defined (necessary when the lazy module provides any service in order to injection works well) and the template of the referenced component should have an element with the <router-outlet> directive. This route usually has a children property.
  • The value of the path property of the lazy route defined in the "app-routing.module" ("lazyModulePrefix" in my example) would be the prefix of all the paths defined in the ".lazy-routing.module".

For example:

///////////// app-routing.module.ts /////////////////////
import { NgModule  } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { LoginComponent } from './login/login.component';
import { PageNotFoundComponent } from './page-not-found.component';

const appRoutes: Routes = [
  { path: 'login', component: LoginComponent },
  { path: 'lazyModulePrefix', loadChildren: 'app/lazyModulePath/lazy.module#LazyModule' }, // 
  { path: '', redirectTo: 'login', pathMatch: 'full'},
  { path: '**', component: PageNotFoundComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(appRoutes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

.

///////////// lazy-routing.module.ts /////////////////////
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { LazyModuleRootComponent } from './lazy-module-root.component';
import { LazyModuleHomeComponent } from './lazy-module-home.component';
import { AComponentDeclaredInTheLazyModule1 } from './a-component-declared-in-the-lazy-module-1.component';
import { AComponentDeclaredInTheLazyModule2 } from './a-component-declared-in-the-lazy-module-2.component';

const lazyModuleRoutes: Routes = [ // IMPORTANT: this array should contain a single route element with an empty path. And optionally, as many children as desired.
    { path: '',
      component: LazyModuleRootComponent, // the `component` property is necessary when the lazy module provides some service in order to injection work well. If defined, the referenced component's template should have an element with the `<router-outlet>` directive.
      children: [ 
        { path: '', component: LazyModuleHomeComponent }, // this component has no diference with the other children except for the shorter route.
        { path: 'somePath1', component: AComponentDeclaredInTheLazyModule1 },
        { path: 'somePath2', component: AComponentDeclaredInTheLazyModule2 },
    ] } 
];

@NgModule({
    imports: [RouterModule.forChild(lazyModuleRoutes)],
    exports: [RouterModule]
})
export class LazyRoutingModule { }

.

//////////////////// lazy.module.ts ////////////////////
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { SharedModule } from '../shared/shared.module';
import { LazyRoutingModule } from './lazy-routing.module';
import { LazyModuleRootComponent } from './lazy-module-root.component';
import { LazyModuleHomeComponent } from './lazy-module-home.component';
import { AComponentDeclaredInTheLazyModule1 } from './a-component-declared-in-the-lazy-module-1.component';
import { AComponentDeclaredInTheLazyModule2 } from './a-component-declared-in-the-lazy-module-2.component';

@NgModule({
    imports: [
        CommonModule,
        SharedModule,
        LazyRoutingModule,
    ],
    declarations: [
        LazyModuleRootComponent,
        LazyModuleHomeComponent,
        AComponentDeclaredInTheLazyModule1,
        AComponentDeclaredInTheLazyModule2,
    ]
})
export class LazyModule { }

.

//////////////// lazy-module-root.component.ts //////////////////
import { Component } from '@angular/core';

@Component({
    template: '<router-outlet></router-outlet>'
})
export class LazyModueRootComponent { }

With the above code, the routes mapping would be:

http://host/login -> LoginComponent

http://host/lazyModulePrefix -> LazyModuleHomeComponent

http://host/lazyModulePrefix/somePath1 -> AComponentDeclaredInTheLazyModule1

http://host/lazyModulePrefix/somePath2 -> AComponentDeclaredInTheLazyModule2

http://host/anythingElse -> PageNotFoundComponent

Comments

8

Long story short: I met this error when didn't insert (forgot) child routes to the feature module:

landings.routing.ts export const LandingsRoutes = RouterModule.forChild(routes);

landings.module.ts

imports: [
    CommonModule,
    // LandingsRoutes // <-- this I forgot and receive error Callstack exceeded
  ]

If you don't export the routing module as a module - you need to export the only router with routes. Only forgotten things cause errors

Comments

2

I had the same error. I had four modules inside my angular app.

ERROR in Maximum call stack size exceeded

My Error

I had created a routing file inside a module manually and that file was not imported in module.ts file. So you need to import the routing file in your module.ts file.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { UserLoginComponent } from './user-login/user-login.component';
import { UserSignupComponent } from './user-signup/user-signup.component';
import { PublicComponent } from './public/public.component';
import { PublicRoutingModule } from './public-routing.modue'; //import it first

@NgModule({
  declarations: [UserLoginComponent, UserSignupComponent, PublicComponent],
  imports: [
    CommonModule,
    PublicRoutingModule // I was missing this line
  ]
})
export class PublicModule { }

Alert: This module file is not app.module.ts

Comments

1

Try removing comments. When I updated my router to current in the application I was working on I commented a bunch of stuff out from the old router because I didn't want to lose it. After removing comments some of the strange errors went away.

Comments

1

Above answers are good. Check out your imports - probably you forgot to import module. You can also check your typescript package version. In my case in Angular 5, I had a warning in CLI:

@angular/[email protected] requires typescript@'>=2.4.2 <2.5.0' but 2.5.3 was found instead. Using this version can result in undefined behaviour and difficult to debug problems. Please run the following command to install a compatible version of TypeScript.

npm install typescript@'>=2.4.2 <2.5.0' --save

This can also make errors.

Comments

0

I was facing same issue and I had everything correct. The following worked for me

  1. Stop the angular server
  2. Start the server again with ng serve

It started working again spontaneously. First make sure you have everything correct as mentioned in other answers and then try this.

Comments

0

Import routing component to a module.

In your EncounterModule.ts

import:[
   AppRoutingModule 
]

Comments

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.