1

I have main AppRoutingModule class where I set my routes and add in my appModule:

const appRoutes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'shopCart', component: ShopCartComponent },
  { path: 'administration', loadChildren: './admin/admin.module#AdminModule' },
  { path: 'productsList', loadChildren: './products/products.module#ProductsModule' },
  { path: 'not-found', component: PageNotFoundComponent, data: { message: 'Page not found!' } },
  { path: '**', redirectTo: '/not-found' }
];

@NgModule({
  imports: [RouterModule.forRoot(appRoutes, { preloadingStrategy: PreloadAllModules })

  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

In appModuleI am add in imports module

ModalModule.forRoot(),
NgbModule.forRoot(),

And in providers I am add NgbActiveModal. I want to lazy load admin.module and in this module I have modal.

My admin.module is :

@NgModule({
  imports: [
    CommonModule,
    ReactiveFormsModule,
    FormsModule,
    AdminRoutingModule,
    NgbModule,
    AlertModule.forRoot()

  ],
  declarations: [
    AdminComponent,
    CategoryComponent,
    ProductModal

  ]
  , entryComponents: [
    CategoryComponent,
    ProductModal
  ]

})
export class AdminModule { } 

All work good and that I click on the my modal I click on the modal, I have error :

ERROR Error: No component factory found for CategoryComponent. Did you add it to @NgModule.entryComponents? 

I followed this link link

I want to mention, everything was working good before Lazy loading.

0m3r
  • 12,286
  • 15
  • 35
  • 71
Kin Jong
  • 65
  • 1
  • 6

1 Answers1

3

You have to move your dynamic components to a higher level so that angular can find them if you want create them without using ng-templates

So in your case you add this to your app.module.ts

    @NgModule({
      declarations: [
        // Other imports....

      ],
      entryComponents: [
        CategoryComponent,
        ProductModal
      ],
      providers: [
           // other providers...
        ],
      bootstrap: [AppComponent],


    })
    export class AppModule { }

Remove this from admin.module.ts

@NgModule({
  imports: [
    // Other Imports....    
  ],
  declarations: [
    AdminComponent,
    // CategoryComponent, -> Removed
    // ProductModal -> Removed

  ]
  , entryComponents: [
    // CategoryComponent, -> Removed
    // ProductModal -> Removed
  ]

})
export class AdminModule { }

This should make your application generate Modals.

You can read more about entryComponents here

Another Simpler Solution

Move the Modal.forRoot() method to the LazyLoaded Module admin.module.ts

so your admin.module.ts becomes

@NgModule({
  imports: [
    // Add this, Remove for `app.module.ts`
    ModalModule.forRoot(),

  ],
  declarations: [
    AdminComponent,
    CategoryComponent,
    ProductModal

  ]
  , entryComponents: [
    CategoryComponent,
    ProductModal
  ]

})
export class AdminModule { }
Ankesh
  • 4,847
  • 4
  • 38
  • 76
  • If this helped please accept the answer, this will help others when they see this :) – Ankesh Dec 25 '18 at 19:30
  • This works, but it is not really the correct answer. The problem with this is it breaks the angular module flow. If i did this i would end up having 50 components in my main module. – Samuel Thompson May 20 '19 at 16:30
  • @SamuelThompson you should use dynamic module loading. I think the component forces you to declare components in the module where you are doing `forRoot()` (I may be wrong, check the documentation for this). – Ankesh May 21 '19 at 09:25
  • You are correct, and that is the only way of doing it... but at the same time, it is a really bad way of doing it. Right now ngx-bootstrap is broken in that sense. There is no real good solution to the problem. – Samuel Thompson May 21 '19 at 18:09