Lazy loaded module, Mdb-date-picker LocaleService error


Topic: Lazy loaded module, Mdb-date-picker LocaleService error

bitjuice pro asked 4 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:

enter image description here

How can I fix it?

Thanks

Marco


Arkadiusz Idzikowski staff commented 4 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?


bitjuice pro answered 4 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:

enter image description here

And also with DropdownModule:

enter image description here

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


Arkadiusz Idzikowski staff answered 4 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:

  1. Created BasicModalsModule using code from your example
  2. Created a new BasicComponent (using ng g c basic) and declared it inside the BasicModalsModule.

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 commented 4 years ago

Ok thanks Arkadiusz, I will try this way

Marco


bitjuice pro commented 2 years ago

Hi Arkadiusz,

componentFactoryResolver and createComponent are deprecated since Angular 13. How ca I update my code?

Thanks a lot


bitjuice pro answered 2 years ago

Hi Arkadiusz,

componentFactoryResolver and createComponent are deprecated since Angular 13. How ca I update my code?

Thanks a lot


Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue
  • User: 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