Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ERROR TypeError: Cannot read property 'createComponent' of undefined in angular 4

I am new in angular 4 and i am using "dynamic component loading" for making project, but there is issue of createComponent for loading component.

component In above image there is four sections.

  1. Top section(headerComponent)
  2. Events section (EventsComponent) Note:- Event Section has two dynamic component (2.1, 2.2)
    2.1. Event detail section(EventDetailComponent) of particular event 2.2. User form section (UserFormComponent)

When click on "Event" tab from top header we are hitting event api and showing events in left side bar and then hit event detail api load "2.1 event details" screen. when click on show user then again load "2.2 User Form" dynamic form.

Issue:- when hitting the api of event detail of particular event and api is now waiting state and then user click on "create event" tab then it is going to create event screen and again user click on event tab then showing createComponent Error for event detail. also clicking on add user button then again showing the same error.

Code:-

ngAfterViewInit() {
  this.getEventList('init');
}

public getEventList(listsource) {
  this.appService.getJsonRequest(AppSettings.EVENT_LIST).subscribe(result => {
    if (result.status === 200  && result.events) {
      this.events = result.events;
      this.publicEvents = result.events;
      this.events[0].selected = true;
      this.selectedEVentInfo = this.events[0];
      this.noImgFlag = true;
      this.eventDetailFlag = false;
        this.eventDetailInfo(listsource); 
    } else {
      this.loaderMsg = AppSettings.EVENT_LIST_ERROR_MSG;
    }
    // this.loaderFlag = false;
  }, err => {
    this.loaderMsg = AppSettings.EVENT_LIST_ERROR_MSG;
    this.loaderFlag = false;
    this.snackBar.open(err, AppSettings.CLOSE, {
      duration: AppSettings.DURATION,
    });
  });
}


  eventDetailInfo  (event, source: String = null) { // event detail
   console.log('### Get event detail information');
   if (this.eventDetailFlag === false) {
    if ((source === 'list' || source === 'delete' || source === 'stripe') && this.ed !== undefined) { // testing needed
      console.log('clear');
      this.ed.clear();
    }

        let edCompFactory: ComponentFactory<any>;
        edCompFactory = this.compFactoryResolver.resolveComponentFactory(EdComponent);
        const componentRef = this.ed.createComponent(edCompFactory);
        (<EdComponent>componentRef.instance).event = this.selectedEVentInfo;
      }
   }
 }

Code of Add User:-

expandAddEventMember(fullWidth) {
if (this.fullWidth === true && fullWidth === true) {
  console.log('Before');
    if (this.am !== undefined) {
      this.am.clear();
    }
  // setTimeout(() => {
    let amCompFactory: ComponentFactory<any>;
    amCompFactory = this.compFactoryResolver.resolveComponentFactory(AmComponent);
    const componentRef = this.am.createComponent(amCompFactory);
    (<AmComponent>componentRef.instance).event = this.selectedEVentInfo;
    this.fullWidth = false;
  // }, 100);
  }
}

Error:- enter image description here

Here is my entryComponent

  entryComponents: [
AppComponent,
ForgotModalComponent,
EventDetailsModalComponent,
AddManagerModalComponent,
AddAdminModalComponent,
CopyLinkModalComponent,
OrderSummaryModalComponent,
EventPreviewModalComponent,
PaidMemberModalComponent,
SendMessageModalComponent,
TicketInfoModalComponent,
AddPaidMemberModalComponent,
MessageModalComponent,
TicketCheckInDetailModalComponent,
SaleItemModalComponent,
SaleItemListModalComponent,
ApmComponent,
PmComponent,
AsmComponent,
SlmComponent,
TiComponent,
EdComponent,
AmComponent,
SihComponent,
ImageModalComponent,
GoogleMapModalComponent
]
like image 533
Sharma Vikram Avatar asked Apr 02 '26 22:04

Sharma Vikram


1 Answers

You just need to make sure that am and em are instantiated before creating the component.I assume that they can be undefined, since in your code, you already check if am or em is instantiated if(this.am !== undefined) at some stage (before calling clear), but not for calling createComponent. It's just that you need to include our createComponent code inside the if

  eventDetailInfo(event, source: String = null)
  { // event detail
    console.log('### Get event detail information');
    if (this.eventDetailFlag === false)
    {
      if ((source === 'list' || source === 'delete' || source === 'stripe') && this.ed !== undefined)
      { // testing needed
        console.log('clear');
        this.ed.clear();
        /*}  <======= Remove this bracket*/

        let edCompFactory: ComponentFactory<any>;
        edCompFactory = this.compFactoryResolver.resolveComponentFactory(EdComponent);
        const componentRef = this.ed.createComponent(edCompFactory);
        (<EdComponent>componentRef.instance).event = this.selectedEVentInfo;
      }/* <========== Add it here */

    }
  }

Same for addUser

  expandAddEventMember(fullWidth)
  {
    if (this.fullWidth === true && fullWidth === true)
    {
      console.log('Before');
      if (this.am !== undefined)
      {
        this.am.clear();
        /* } <=== Remove this bracket **/
        let amCompFactory: ComponentFactory<any>;
        amCompFactory = this.compFactoryResolver.resolveComponentFactory(AmComponent);
        const componentRef = this.am.createComponent(amCompFactory);
        (<AmComponent>componentRef.instance).event = this.selectedEVentInfo;
        this.fullWidth = false;
      } /** <==== Add it here */

    }
  }

Edit: Regarding your comment about normalizing it, you should probably open another question since it's a completely different problem. The following piece of codemay not work (not tested) but could give you an idea of an approach

@Injectable()
export class CompFactoryHelper
{
  constructor(private resolver: ComponentFactoryResolver)
  {

  }

public createAndAddComponent(containerRef: ViewContainerRef, eventInfo : any, type: any)
   {
        containerRef.clear();
        let compFactory = this.resolver.resolveComponentFactory(type);
        const componentRef = containerRef.createComponent(compFactory);
        (componentRef.instance as any).event = eventInfo;
   }
}

and in your components

 expandAddEventMember(fullWidth)
  {
    if (this.fullWidth === true && fullWidth === true)
    {
      console.log('Before');
      if (this.am !== undefined)
      {
        this.compFactoryHelper.createAndAddComponent(this.am,  this.selectedEVentInfo, AmComponent);

      } 

    }
  }
like image 106
David Avatar answered Apr 08 '26 06:04

David



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!