Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dynamically render a component in lazy loaded module with AOT throws cant find component factory

Current behavior

I declared those dynamic components as entry components in the module where I also want to render them. With JIT it works fine. Following structure has the part of my app I want to render them: app -> home (lazy) -> contracts (lazy) -> search.

So I added those components to the module I use for the search component/route. When I'm compiling with AOT, everytime I visit the search route, the app tells me there is no component factory. Of course I searched google and found some results:

I tried adding them to the ANALYZE_FOR_ENTRY_COMPONENTS provider, I tried to import a ModuleWithProviders with .forRoot() in my app.module and I also tried simply importing and declaring my dynamic and all of its dependant components in the root module (app.module). Everything resulting in the same error.

I declare my dynamic components as entry components like so:

@NgModule({
  imports: [SharedComponentsModule, FinoSchemaFormsModule, TabGroupModule, FinoInputModule],
  declarations: [EnergySearchSettingsComponent, DslSearchSettingsComponent, MobileSearchSettingsComponent, ComparisonDetailSectionComponent],
  entryComponents: [EnergySearchSettingsComponent, DslSearchSettingsComponent, MobileSearchSettingsComponent],
  exports: [EnergySearchSettingsComponent, DslSearchSettingsComponent, MobileSearchSettingsComponent, ComparisonDetailSectionComponent],
  providers: [CategoryMappingProvider]
})
export class ComparisonComponentsModule { }

This module gets imported in the SearchModule, where also my SearchComponent is declared. In this component I want to render those components dynamically using the ComponentFactoryResolver I inject in the SearchComponent.

ngOnInit() {
    this.searchSettingsComponent = this.comparisonService.getSearchComponent(); // returns either EnergySearchSettingsComponent, DslSearchSettingsComponent or MobileSearchSettingsComponent
    let componentFactory = this.componentFactoryResolver.resolveComponentFactory(searchSettingsComponent);
    this.searchSettingsComponent = this.searchContainer.createComponent(componentFactory);
    this.searchSettingsComponent.instance.comparisonSettings = comparisonSettings;
    this.searchSettingsComponent.instance.onSave.subscribe(settings => this.saveSearchSettings(settings));
}

The SearchComponent is the routing component of the search route, which is a child route of my contract route, which gets lazy loaded. This again is a child route of my home route (also lazy loaded) and this belongs to the main route.

Environment

Angular version: 5.2.4

For Tooling issues:
- Node version: 8.11.3
- Platform:  Mac
like image 868
Florian Gl Avatar asked Oct 23 '18 11:10

Florian Gl


1 Answers

It must be pretty simple. Just create the SharedModule and put all reusable dynamic component in it, export those components from SharedModule and import this Module in all required. Lazy loaded Modules.

Since it is imported direct to the Module, it must be available while creating the Dynamic Component.

like image 68
Sunil Singh Avatar answered Sep 18 '22 11:09

Sunil Singh