63

I am trying to implement Lazy Loading into my application but seem to be coming across an issue whereby I get the error message :

Error: RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.

So I have my main app-routing.module.ts and also app-module.ts which looks like below:

app-module.ts

// External Dependencies
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

// Internal Dependencies
import { MaterialModule } from '../app/configuration/material/material.module';
import { SharedModule } from '../app/application/shared/shared.module';
import { RoutingModule } from '../app/configuration/routing/routing.module';
import { SettingsModule } from '../app/application/settings/settings.module';

import { AppComponent } from './app.component';

import { SearchService } from './application/shared/services/search.service';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserAnimationsModule,
    BrowserModule,
    SharedModule,
    RoutingModule,
    MaterialModule,
    HttpClientModule,
    FormsModule,
  ],
  providers: [ ],
  bootstrap: [AppComponent]
})

export class AppModule { }

app-routing.ts

// External Dependencies
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';
import { HttpModule } from '@angular/http';

const appRoutes: Routes = [
  { path: '', redirectTo: 'overview', pathMatch: 'full' },
  { path: 'overview', loadChildren: '../../application/overview/overview.module#OverviewModule' },
  { path: 'search', loadChildren: '../../application/search/search.module#SearchModule' },  
  { path: 'policy/:id', loadChildren: '../../application/policy/policy.module#PolicyModule' },
  { path: 'claim/:id', loadChildren: '../../application/claim/claim.module#ClaimModule' },
  { path: 'settings', loadChildren: '../../application/settings/settings.module#SettingsModule' }
];

@NgModule({
  imports: [
    CommonModule,
    RouterModule.forRoot(appRoutes)
  ],
  exports: [
    RouterModule
  ],
  declarations: []
})

export class RoutingModule { }

This works fine and the application correctly loads. The issue from here is that in the SharedModule it has come components to redirect the user using routerLink to a new page.

shared.module.ts

// External Dependencies
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CalendarModule } from 'primeng/calendar';
import { AgmCoreModule } from '@agm/core';
import { FroalaEditorModule, FroalaViewModule } from 'angular-froala-wysiwyg';
import { PdfViewerModule } from 'ng2-pdf-viewer';

// Internal Dependencies
import { MaterialModule } from '../../configuration/material/material.module';
import { RoutingModule } from '../../configuration/routing/routing.module';

import { NavbarTopComponent } from '../../application/shared/components/navbar-top/navbar-top.component';
import { NavbarSideComponent } from './components/navbar-side/navbar-side.component';
import { TemplateCardWComponent } from './components/template-card-w/template-card-w.component';
import { FilterPipe } from './pipes/filter.pipe';
import { StandardTableComponent } from './components/standard-table/standard-table.component';
import { OrderPipe } from '../shared/pipes/order.pipe';
import { ActionComponent } from './components/action/action.component';
import { GoogleMapComponent } from './components/google-map/google-map.component';
import { HtmlEditorComponent } from './components/html-editor/html-editor.component';
import { PdfViewerComponent } from './components/pdf-viewer/pdf-viewer.component';
import { KeyBindingPipe } from './pipes/key-binding.pipe';
import { StandardEditTableComponent } from './components/standard-edit-table/standard-edit-table.component';

@NgModule({
  imports: [
    CommonModule,
    MaterialModule,
    RoutingModule,
    FormsModule,
    CalendarModule,
    AgmCoreModule,
    FroalaEditorModule,
    FroalaViewModule,
    PdfViewerModule
  ],
  declarations: [
    NavbarTopComponent,
    NavbarSideComponent,
    TemplateCardWComponent,
    FilterPipe,
    StandardTableComponent,
    OrderPipe,
    ActionComponent,
    GoogleMapComponent,
    HtmlEditorComponent,
    PdfViewerComponent,
    KeyBindingPipe,
    StandardEditTableComponent
  ],
  exports: [
  ]
})

export class SharedModule { }

As you can see I am having to import the RouterModule. If I remove the RouterModule, the application will load but no re-direct. If I keep the RouterModule the application will cause the error at the top of the question.

Could anyone help me on this.

Nicholas K
  • 15,148
  • 7
  • 31
  • 57
Ben Clarke
  • 1,443
  • 2
  • 10
  • 16

16 Answers16

161

I got this error because I somehow accidentally imported the root AppModule into my lazy-loaded module. This caused the root AppRoutingModule to be called again when the lazy-loaded module was loaded, and thus RouterModule.forRoot was called twice.

If you are certain you aren't calling RouterModule.forRoot twice then this could be the cause of the issue. Check that you aren't importing any modules in your lazy-loaded module that direcly call RouterModule.forRoot or import a module that calls RouterModule.forRoot.

inorganik
  • 24,255
  • 17
  • 90
  • 114
  • 5
    It means, when you create a feature module inside a feature module, you might need an extra shared module. For instance, you have a RegisterModule with all stuff related to registration, and an SmsRegisterModule, which has some rarely used stuff so you want it to load lazily. But SmsRegisterModule might be using some components from RegisterModule. If you just import parent module inside its child, you gonna have a "called twice" problem. So you create a SharedRegisterModule, in which you put components used in both RegisterModule and SmsRegisterModule. And import SharedRegisterModule in both. – Anton Rusak Sep 24 '18 at 14:56
  • 1
    Thanks. Fixed. I got this error because I somehow accidentally imported the root AppModule into my lazy-loaded module. – SUHAIL KC Dec 23 '19 at 07:25
  • 2
    Same in my case: AppModule got imported into my lazy-loaded module. I somehow have the feeling, that it was coded automatically with Intellij IDEA. Good answer, thank you! – Jochen Haßfurter Feb 09 '20 at 10:24
  • 2
    The "somehow" in my case was my IDE (WebStorm) trying to "intelligently" fix a pipe import. Pro tip: use a custom pipes module! – Alex Steinberg Apr 25 '20 at 19:03
  • Wow, how did I miss this? Thanks a bunch. – edwardbrosens May 11 '20 at 20:13
  • 1
    @edwardbrosens, in my case WebStorm imported it for me when I used a top-level pipe in a child component so it wasn't me but auto import magic gone wrong. – Tyrone Wilson Jun 02 '20 at 21:13
  • Fixed it. I happened to import the root `RouterModule` in the child's module too. Removing solved it like magic. – John Erbynn Jul 19 '20 at 07:48
  • Same reason for me. – Ojonugwa Jude Ochalifu Jan 27 '21 at 07:48
  • Had the same error but I found that AppModule was accidently imported to one the shared modules. Thanks ! – faye.babacar78 Jun 23 '21 at 18:44
  • Thank you! This was my issue as well – Артур Гудиев Nov 20 '21 at 07:58
33

I've been struggling with this for a while. Finally found the issue.

I'm using lazy loading. And even though I'd only used .forRoot in one place in the app, the error suggested that I was using it twice.

Turned out that I was importing the AppRoutingModule from app.routing.ts file in one of the feature modules that was being lazy loaded. And I had done this earlier because it kept saying it didn't recognize routerLink which I had used in one of the components in that feature module.

The solution was to replace the AppRoutingModule import in the feature module with an import of the RouterModule from '@angular/router'. Now everything works.

PS - when I say feature module, I mean sub module that I'm lazy loading.

Ragav Y
  • 1,662
  • 1
  • 18
  • 32
  • I find this very confusing. I'm getting the exact same problem RouterModule.forRoot() called twice since I'm importing AppRoutingModule in a SharedModule, and the SharedModule is also used in a Lazy loaded module. SharedModule has a breadcrumb component that uses the routerLink. Importing just RouterModule makes all work again. But this goes against Angular documentation: "RouterModule can be imported multiple times: once per lazily-loaded bundle. " https://angular.io/api/router/RouterModule#usage-notes – carraua Jan 30 '20 at 11:48
14

I have faced the problem too, and for the future comers, This is my solution.

Do not import AppRoutingModule in oer module, Import RoutingModule

It will be solved. Here is an example.

import { RouterModule } from '@angular/router';

And in the imports array

  @NgModule({

 declaration: [], // your contents
 imports: [
  RouterModule,
  // Other modules
 ]
  })
Abhishek Soni
  • 563
  • 1
  • 6
  • 17
8

In your separate lazily loaded modules, OverviewModule, SearchModule, PolicyModule, ClaimModule and SettingsModule do you have routes declared in them? If so, in the @NgModule of each do you have a RouterModule.forRoot() somewhere? They should be RouterModule.forChild(...). It sounds like that could be the issue.

rrd
  • 5,789
  • 3
  • 28
  • 36
  • Yes, each module I.E. OverviewModule has its own overview-routing.module.ts file which inside contains a RouterModule.forChild() – Ben Clarke Apr 05 '18 at 10:44
8

instead of using

  imports: [
    CommonModule,
    RouterModule.forRoot(appRoutes)
     ],

use

 imports: [
    CommonModule,
    RouterModule.forChild(appRoutes)
     ],
7

I know this is an old post but I recently encountered this issue because I was unknowingly importing AppModule into a child module.

My IDE had I pop-up I clicked unintentionally and that added AppModule to my imports. Something to search for if you encounter this problem!

Jeremy Thomas
  • 6,240
  • 9
  • 47
  • 92
6

Convert the routing module from

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

to

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

that will solve the error

sanjay
  • 695
  • 11
  • 22
3

I got this error when I mistakenly named the route module of my lazy loaded module AppRoutingModule.

I renamed to match the module name eg StockRoutingModule and it was fixed.

Winnipass
  • 904
  • 11
  • 22
2

Use RouterModule.forChild(routes) inside child module. Like this file ../../application/overview/overview.module.

If you have more child modules then use RouterModule.forChild(yourarray) instead of RouterModule.forRoot(yourarray)

Nicholas K
  • 15,148
  • 7
  • 31
  • 57
Bhumika Barad
  • 101
  • 1
  • 5
2

I've faced this issue because I use RouterModule.forRoot(myRoutes) inside my child module which I lazy-loaded. It should've been

@NgModule({
  imports: [ RouterModule.forChild(myRoutes) ], // changed forRoot with forChild
  exports: [ RouterModule ]
})
Kirubel
  • 1,461
  • 1
  • 14
  • 33
0

You don't import RouterModule into your SharedModule. You import RoutingModule there. And this module imports RouterModule with forRoot which is called second time when lazy loading it. This causes the error.

Instead you should import RouterModule directly if you need redirects.

shared.module.ts

@NgModule({
  imports: [
  CommonModule,
  MaterialModule,
  RouterModule, /* NOT RoutingModule */
  FormsModule,
  CalendarModule,
  AgmCoreModule,
  FroalaEditorModule,
  FroalaViewModule,
  PdfViewerModule
],
Episodex
  • 4,479
  • 3
  • 41
  • 58
0

I was also facing the same while using lazy loading. Finally i have found some solution.

I have removed "routingModule" and "routerModule" from sharedModule and using routerModule only in respective routing.module.ts file.

sharad jain
  • 1,471
  • 13
  • 9
0

In my case the issue was that I had forgotten to add the type when declaring my routes array in the feature module, If you have made sure that forRoot is not called twice and neither is AppRoutingModule imported multiple times you can check for basic mistakes like the one I made.

It was defined as:

const feature_routes = [.....];

instead of:

const feature_routes : Routes = [.....];
סטנלי גרונן
  • 2,917
  • 23
  • 46
  • 68
0

In my case I used forRoot(routes) in App Modules and all other modules as well.

To get rid of this error I just put forRoot(route) in App module and changed all other modules to forChild(routes).

That's it. It works for me amazingly!

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Naveen
  • 43
  • 6
0

I think I've got the solution to this problem. In the shared.module.ts file you added RoutingModule to the array of imports and again in the app.module.ts file you imported both the SharedModule (which already contains the RoutingModule) and the RoutingModule.

Simply remove the RoutingModule from the imports: array in the shared.module.ts file.

0
***app.module.ts***

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { RouterModule } from '@angular/router';
    import { AppRoutingModule } from './app-routing.module'
     
    import { SessionManagementStorageRoutingModule } from './sessionmagement/sessionmanagement-routting.module';
    
    @NgModule({
      declarations: [
        AppComponent,
        ErrorComponent,
        Covid19Component,
      ],
      imports: [
        BrowserModule,
        RouterModule,
        AppRoutingModule,
        HttpClientModule,
        MatTableModule,
        // FormsModule,
       InMemoryWebApiModule.forRoot(TestData),
       SessionManagementStorageRoutingModule
      ],
      providers: [CustompreloadingstartegyService, CustompreloadingdelaystartegyService, Covid19Service
        // BookService
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule {
      constructor() {
        console.log('App module called');
      }
    }


**app-routing.module.ts**

import { NgModule } from '@angular/core';
import { RouterModule, Routes, PreloadAllModules } from '@angular/router';
import { CustompreloadingstatregybookserviceService } from './service/custompreloadingstatregybookservice.service';

const routes: Routes = [
  { path: 'company', loadChildren: () => import('./company/company-module').then((x) => x.ComapanyModule), data:{preload:true} },
  { path: 'login', loadChildren: () => import('./auth/auth.module').then((m) => m.AuthModule), data:{preload:true, delay:true}},
  { path: 'covid19', component:Covid19Component },
  { path: 'book', loadChildren : ()=> import ('./book/book.module').then((module)=>module.BookModule), data:{preload:true, delay:true}},
  { path: 'sessionmanagement', loadChildren:()=> import ('./sessionmagement/sessionmagement.module').then((x)=>x.SessionmagementModule) },
  { path: '**', component: ErrorComponent }
 ];

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

Sessionmagement-routing.Module.ts

import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { LocalvssessionStorageComponent } from "./localvssession-storage/localvssession-storage.component";
import { SessionmagementComponent } from "./sessionmagement.component";
import { SessionvslocallStorageComponent } from "./sessionvslocall-storage/sessionvslocall-storage.component";

const routes: Routes = [{
    path:'',
    component:SessionmagementComponent,
    children:[{
        path: 'local', 
        component:LocalvssessionStorageComponent
    },
    {
        path:'session', 
        component:SessionvslocallStorageComponent
    }
]
}];

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

export class SessionManagementStorageRoutingModule {}






***Sessionmagement.Module.ts***

@NgModule({
  declarations: [
    SessionmagementComponent,
    LocalvssessionStorageComponent,
    SessionvslocallStorageComponent
  ],
  imports: [
    CommonModule,
    AppRoutingModule  /// This is the main cause of error => please replay with route module.. 
  ],
  exports: [
    SessionmagementComponent
  ]
})
export class SessionmagementModule { }

In my case what is did I replaced the AppRoutingModule with RouterModule in the SessionmagementModule.module.ts

**** Please check the example thoroughly.