The Lazy routing feature in Angular 2 has caused a RangeError due to exceeding the maximum call stack

I'm currently working on incorporating lazy routing into my application.

Previously, in my large project when using a deprecated router, I utilized AsyncRoute. However, now that it has been removed, I attempted to implement the latest lazy loading feature, but encountered an issue with a RangeError: Maximum call stack size exceeded. I followed the instructions in the code, so I'm not sure what went wrong. Could you please take a look?

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 {  }

Below is the 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);

Answer №1

Understanding loadChildren and Module Routing in Angular

When using the loadChildren property in a route, it is essential to reference a module that has a routing system implemented. This means only referencing a module that imports RoutingModule and configures it using the 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';   //Includes multiple shared components/directives/pipes
/* ---------------  !App outer modules  --------------- */


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

export const encountersModuleRoutes: Routes = [
  /* Configure routes for Encounters module here */
];


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


export class EncountersModule {  }

Answer №2

After reviewing the documentation (2.4.2) and examples in the "Angular Modules" and "Routing & Navigation" guides, I have come up with a pattern that may be helpful:

  • Ensure that the lazy module has its own routing module.
  • In the "lazy-routing.module," define a routes array with a single element. The element should have an empty string for the path property, a defined component property (necessary for handling injections), and a template with a <router-outlet> directive. This route can also have children.
  • The path property value of the lazy route in the "app-routing.module" ("lazyModulePrefix" in the example) should be the prefix for all paths in the ".lazy-routing.module".

For instance:

///////////// 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 = [
    { path: '',
      component: LazyModuleRootComponent,
      children: [ 
        { path: '', component: LazyModuleHomeComponent },
        { 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 this setup, the routes are mapped as follows:

-> LoginComponent

-> LazyModuleHomeComponent

-> AComponentDeclaredInTheLazyModule1

-> AComponentDeclaredInTheLazyModule2

-> PageNotFoundComponent

Answer №3

In a nutshell: The issue arose when I failed to add child routes to the feature module:

landings.routing.ts

export const LandingsRoutes = RouterModule.forChild(routes);

landings.module.ts

imports: [
    CommonModule,
    // LandingsRoutes // <-- I overlooked this and encountered a Callstack exceeded error
  ]

If you forget to export the routing module as a module, ensure you export only the router with routes. Neglecting details like this can lead to errors.

Answer №4

I encountered a similar issue in my angular app with four modules.

ERROR in Maximum call stack size exceeded

What Went Wrong

Upon investigation, I discovered that I had manually created a routing file within one of my modules but forgot to import it in the module.ts file. It turns out that importing the routing file in the module.ts file is essential to avoid this error.

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'; //don't forget to import this

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

Reminder: The module file mentioned above is not app.module.ts

Answer №5

Removing comments can make a big difference. I recently updated my router in the app I was developing and decided to comment out a lot of code from the previous router to keep it safe. Surprisingly, after removing the comments, many of the unusual errors disappeared.

Answer №6

The previous responses have been helpful. Make sure to double-check your imports - it's possible you may have forgotten to import a module. Also, verify the version of your typescript package. For instance, when I was working with Angular 5, I encountered a warning in the CLI:

@angular/[email protected] requires typescript@'>=2.4.2 <2.5.0' but 2.5.3 was found instead. Using this version can lead to unpredictable behavior and challenging-to-diagnose issues. To address this, execute the following command to install a compatible version of TypeScript:

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

Failure to rectify this could lead to further errors.

Answer №7

I encountered a similar issue despite having everything set up correctly. I found a solution that worked for me:

  1. Stop the angular server
  2. Restart the server using ng serve

It miraculously started functioning again after following these steps. Make sure you have all the configurations correct as mentioned in other responses before trying this fix.

Answer №8

How to include a routing component in a module

When working on your EncounterModule.ts file, make sure to include the routing component by adding the following code:

import:[
   AppRoutingModule 
]

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unable to display animation without first launching it on Rive web

I attempted to incorporate a Rive animation into my Angular web application <canvas riv="checkmark_icon" width="500" height="500"> <riv-animation name="idle" [play]="animate" (load)=&qu ...

Encountering a problem while trying to integrate ng-zorro-antd in an Angular 8 project using the CLI command ng add ng-zorro

I am encountering an issue when trying to integrate ng-zorro-antd with Angular 8 using the CLI. I have followed these steps: Create a new project using 'ng new PROJECT_NAME' Navigate into the project directory using 'cd PROJECT_NAME' ...

Enhancing supertest functionality with Typescript

Currently, I am working on extending the functionality of supertest. After referencing a solution from Extending SuperTest, I was able to implement the following example using javascript: const request = require('supertest'); const Test = reque ...

Having trouble with CSS values not being applied to dynamically injected HTML div elements in Angular 4?

Link to Codepen My Angular calendar application runs smoothly without any errors. However, I am encountering an issue where the CSS styles are not being applied to the page. When I implemented this separately, everything worked fine. But as soon as I inc ...

Updating dynamically rendered component content with ngComponentOutlet in Angular 11: A comprehensive guide

I am working on an Angular 11 app that includes a menu generated from an array of objects with specific properties: { icon: CUSTOMER_ORDER_PROPERTIES.icon, iconColor: CUSTOMER_ORDER_PROPERTIES.color, label: 'Search Customer Order', routeB ...

Removing a selected row from a data table using an HTTP request in Angular 2

I am working with a table that has data retrieved from the server. I need to delete a row by selecting the checkboxes and then clicking the delete button to remove it. Here is the code snippet: ...

Communicating between different components in Angular 11 using a service to share data

In my Angular 11 project, componentB has multiple methods that need to be called from componentA. Although I am aware that transferring these methods to a service would be the proper solution, it requires extensive effort which I want to avoid for now. In ...

What are the best strategies for managing npm dependencies alongside other packages?

I am working on an Angular app that has the following dependencies: "dependencies": { "personalUiLibrary": "1.0.0" }, "devDependencies": { "tailwindcss": "^2.2.7" } In the personalUiLibrary p ...

Utilizing Prisma Enum with Nest JS: A Comprehensive Guide

While working on my backend with Prisma and NestJS, I have encountered an issue. I defined an enum in Prisma that works fine in debug mode, but when I generate the Prisma client using nest build, I get an error. Object.values(client_1.RoomSharingType).join ...

Uploading images using Angular and PHP: A comprehensive guide

I am a beginner in Angular and I am having trouble uploading an image from Angular as I encounter 4 errors: 1) Error in the post method: Cannot find name 'formData'. Did you mean 'FormData'?ts(2552) 2) Error in the subscribe method: ...

Expanding TypographyProps and TextFieldProps for enhanced functionality

Currently, I am developing a React component using TypeScript along with Material UI (MUI). The main purpose of this component is to display either an input field or text based on the mode selected. To switch between these modes, the prop mode is utilize ...

Encountering a hiccup while attempting to initialize a fresh Angular project with the command "ng new my

I encountered an error issue after running the command npm new project0 npm ERR! path D:\Polytech\Génie Informatique\2- Génie Informatique 4\Programmation Web\Angular\project0\node_modules\js-yaml\bin\js ...

Tips for retrieving a nested data value within an array

I am currently puzzled by the undefined error I encounter when attempting to access a value using dot notation. The following illustrates my point: My goal is to retrieve the value from within the nested object in the headline color array: ...

Ensuring correct association of values to avoid redundancies

There are 5 fields available for users to fill out on this form: Leave Code, From Date, Input Time1, To Date, and Input Time2. These variables are declared as a dates object in the .ts file, as shown below. interface Supervisor { name: string; code: s ...

The function of edit does not exist

I'm currently working on creating a discord bot that will send a message to a specific channel upon startup. Initially, I was able to send the message to the designated channel without any issues. However, when I attempted to edit the message, an erro ...

How can I silence the warnings about "defaultProps will be removed"?

I currently have a next.js codebase that is experiencing various bugs that require attention. The console is currently displaying the following warnings: Warning: ArrowLeftInline: Support for defaultProps will be removed from function components in a futur ...

Guide on implementing conditional return types in React Query

In my approach, I have a method that dynamically uses either useQuery or useMutation based on the HTTP method passed as a prop. However, the return type of this method contains 'QueryObserverRefetchErrorResult<any, Error>', which lacks meth ...

Running a single test in Angular without using fdescribe or fit

My project has numerous tests that are not being maintained, causing errors when running ng test due to import issues in .spec.ts files. Is there a way to execute a single file test for a service without having to clean up all the tests? Perhaps using Php ...

Enhance your material-ui component using TypeScript functionality

Exploring ways to enhance the Material-ui Button component by introducing new props. The objective is to introduce a new prop called fontSize with three size options - small, medium, large. <Button variant="outlined" color="primary" ...

Leveraging Global Variables and Functions with Webpack and TypeScript

I have been utilizing Webpack in conjunction with TypeScript, HTML, and SCSS to develop a project. My goal is to create a single page application that incorporates a router located within the root folder of the project /framework/, with all my source code ...