I am having issues with loading a component from a lazy loaded module, using Angular 6.
I created a library using the CLI -
ng generate library @org/chat
Updated angular.json
file to include:
"lazyModules": [
"dist/org/chat"
],
and then loading the module successfully via AppComponent:
constructor(private _injector: Injector, private loader: SystemJsNgModuleLoader, public dialog: MatDialog) {}
load() {
this.loader.load('dist/org/chat#ChatModule').then(moduleFactory => {
const moduleRef = moduleFactory.create(this._injector);
});
}
So far so good and the module is being loaded.
However, the ChatModule has a component called ChatPopupComponent and I can't find a way to show it using a dialog (or by adding it to a ViewChild container).
In order to open a component in a dialog it needs to be declared under the module's entryComponents plus imported at the AppComponent level:
let dialogRef = this.dialog.open(ChatPopupComponent
data: {}
});
But when importing the component directly (and exporting it from the library) I get the following (obvious) error: 'Component ChatPopupComponent is not part of any NgModule or the module has not been imported into your module
'. Since it is a lazy loaded module, it is clearly not imported yet.
When I try the following:
let name: any = 'ChatPopupComponent';
let dialogRef = this.dialog.open(name
data: {}
});
I get the following error - error loading module Error: No component factory found for EmailPopUpComponent. Did you add it to @NgModule.entryComponents?
It seems that the only way to show a component is by importing the module within the app.module.ts
, although it defies the goal of having a lazy loaded module.
Is there a way to do the above or am I missing something rudimental about lazy loading modules & components?
To lazy load the component, we will use the import() method inside an async/await function. The above function first clears the container; otherwise, on every click of the button, the new instance of GreetComponent would be added in the container.
If you're not sure if lazy loading is working correctly, you can open the Chrome DevTools and check that the images are not loaded until the scroll.
To lazy load Angular modules, use loadChildren (instead of component ) in your AppRoutingModule routes configuration as follows. content_copy const routes: Routes = [ { path: 'items', loadChildren: () => import('./items/items.module').then(m => m.ItemsModule) } ];
Lazy loading is the technique used in optimizing your web and mobile apps, this works by rendering only needed or critical user interface items first, then quietly rendering the non-critical items later. As we build code components the application grows, and the bundle gets very cumbersome in size.
try to declare the ChatPopupComponent as a separate module..
chat-popup.component.ts
@NgModule({
imports: [
CommonModule,
...
],
declarations: [ChatPopupComponent],
exports: [ChatPopupComponent],
})
export class ChatPopupModule { }
..do the same for the EmailPopupComponent..
email-popup.component.ts
@NgModule({
imports: [
CommonModule,
...
],
declarations: [EmailPopupComponent],
exports: [EmailPopupComponent],
})
export class EmailPopupModule { }
..and add both modules to the ChatModule imports as well as the entryComponents array..
chat.module.ts
@NgModule({
imports: [
CommonModule,
...
ChatPopupModule,
EmailPopupModule,
],
declarations: [
...
],
entryComponents: [
ChatPopupComponent,
EmailPopupComponent,
]
})
export class ChatModule { }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With