Topic: Lazy loaded module, Mdb-date-picker LocaleService error
bitjuice pro asked 3 years ago
Hi,
I'm using mdb-date-picker in a dynamic modal. Modal component (RegistrationCompletionModalComponent) is declared in a module (BasicModalsModule):
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { WavesModule, DatepickerModule, ButtonsModule, InputsModule, InputUtilitiesModule, CheckboxModule, PreloadersModule, MDBSpinningPreloader } from 'ng-uikit-pro-standard';
import { RegistrationCompletionModalComponent } from './registration-completion-modal/registration-completion-modal.component';
...
@NgModule({
declarations: [
RegistrationCompletionModalComponent
...
],
imports: [
CommonModule,
FormsModule,
ButtonsModule.forRoot(),
InputsModule.forRoot(),
WavesModule.forRoot(),
CheckboxModule,
DatepickerModule,
InputUtilitiesModule,
PreloadersModule
],
exports: [
RegistrationCompletionModalComponent
...
],
entryComponents: [
RegistrationCompletionModalComponent
]
})
export class BasicModalsModule {
}
If I import this module in app.module.ts, everything works fine, but if I manually lazy load BasicModalsModule, when user click on a specific button:
onCompleteRegistrationClick(){
import('../../modals/basic/basic-modals.module').then(m => m.BasicModalsModule).then(m => this.openRegistrationCompletionModal());
}
openRegistrationCompletionModal() {
const modaloptions = {
class: 'modal-lg modal-dialog-scrollable',
backdrop: true,
ignoreBackdropClick: true,
};
this.contactModalRef = this.modalService.show(RegistrationCompletionModalComponent, modaloptions);
}
I get this error:
How can I fix it?
Thanks
Marco
bitjuice pro answered 1 year ago
Hi Arkadiusz,
componentFactoryResolver and createComponent are deprecated since Angular 13. How ca I update my code?
Thanks a lot
Arkadiusz Idzikowski staff answered 3 years ago
@bitjuice I think that in this case, Angular thinks that Datepicker (and other MDB components used inside modal) is part of the root app.module, because even though modal is declared inside BasicModalsModule
, you use ModalService
inside the component that is declared in the root module.
I slightly modified your example to try to fix this problem. Here is what I did:
- Created
BasicModalsModule
using code from your example - Created a new
BasicComponent
(usingng g c basic
) and declared it inside theBasicModalsModule
.
Then on button click I lazy load the module, instantiate it with the compileModuleAsync
method, and lazy load BasicComponent
. When everything is created correctly I open modal from BasicComponent
using componentRef.instance.open();
.
app.component (lazyLoadModule
method is called on button click)
import {
Compiler,
Component,
Injector,
ViewContainerRef,
} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
constructor(
private injector: Injector,
private compiler: Compiler,
private vcr: ViewContainerRef
) {}
async lazyLoadModule() {
const module = await import('./basic-modals.module');
const component = await import('./basic/basic.component');
const moduleFactory = await this.compiler.compileModuleAsync(module.BasicModalsModule);
const moduleRef = moduleFactory.create(this.injector);
const componentFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(component.BasicComponent);
const componentRef = this.vcr.createComponent(
componentFactory,
undefined,
this.injector,
[],
moduleRef
);
componentRef.instance.open();
}
}
BasicModalsModule:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BasicComponent } from './basic/basic.component';
import { ModalComponent } from './modal/modal.component';
import {
ModalModule,
ButtonsModule,
InputsModule,
MdbSelectModule,
DropdownModule,
DatepickerModule
} from 'ng-uikit-pro-standard';
@NgModule({
declarations: [BasicComponent, ModalComponent],
imports: [
CommonModule,
DatepickerModule,
ButtonsModule.forRoot(),
InputsModule.forRoot(),
MdbSelectModule,
ModalModule.forRoot(),
DropdownModule.forRoot(),
],
exports: [],
entryComponents: [ModalComponent],
})
export class BasicModalsModule {}
BasicComponent:
export class BasicComponent implements OnInit {
constructor(private modalService: MDBModalService) {}
ngOnInit(): void {}
open() {
this.modalService.show(ModalComponent);
}
}
ModalComponent
is a standard MDB dynamic modal. I added the mentioned datepicker, select and dropdown components inside and it looks like everything is working correctly.
bitjuice pro answered 3 years ago
Hi Arkadiusz, this is the code of my component:
<mdb-date-picker name="mybirthdate" [(ngModel)]="formattedBirthDate" (dateChanged)="onDateChange($event)"></mdb-date-picker>
formattedBirthDate = "";
onDateChange(event: any): void {
this.user.birthDate = new Date(event.date.year, event.date.month - 1, event.date.day);
}
I noticed that if I import DatepickerModule in app.module it works
I have the same problem with other modules. If I import MdbSelectModule in a module lazy loaded manually I get this error:
And also with DropdownModule:
If I import DatepickerModule or DropdownModule in app.module or in another module lazy loaded by angular routing (https://angular.io/guide/lazy-loading-ngmodules) they work fine.
Thanks for your support
Marco
FREE CONSULTATION
Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.
Answered
- ForumUser: Pro
- Premium support: No
- Technology: MDB Angular
- MDB Version: 10.1.1
- Device: PC
- Browser: Chrome
- OS: Windows 10
- Provided sample code: No
- Provided link: No
Arkadiusz Idzikowski staff commented 3 years ago
@bitjuice
Can you also add the code of the datepicker? Do you use
LocaleService
in your code to set a locale or just render the datepicker component?