Reputation: 2542
I'm using Angular 6 and I want to implement the dynamic addition of components according to the instructions, but I get an error: "Cannot read property 'create' of undefined."
component.html
<mat-card>
<mat-card-header>
<mat-card-title>...</mat-card-title>
</mat-card-header>
<mat-card-content>
<ng-template answerHost></ng-template>
</mat-card-content>
</mat-card>
component.ts
@ViewChild(AnswerHostDirective) answerHost: AnswerHostDirective;
private stepAnswerType1: ComponentFactory<StepAnswerType1Component>;
private stepAnswerType2: ComponentFactory<StepAnswerType2Component>;
private stepAnswerType3: ComponentFactory<StepAnswerType3Component>;
/* ... */
changeStep(id: number) {
let viewContainerRef = this.answerHost.viewContainerRef;
let componentRef;
if (this.step.type == 1) {
componentRef = viewContainerRef.createComponent(this.stepAnswerType1);
}
if (this.step.type == 2) {
componentRef = viewContainerRef.createComponent(this.stepAnswerType2);
}
if (this.step.type == 3) {
componentRef = viewContainerRef.createComponent(this.stepAnswerType3);
}
}
directive
import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[answerHost]'
})
export class AnswerHostDirective {
constructor(public viewContainerRef: ViewContainerRef) { }
}
I tried to replace the directive with a reference to the component's id, but I get the same error. component.html
<mat-card>
<mat-card-header>
<mat-card-title>...</mat-card-title>
</mat-card-header>
<mat-card-content>
<ng-template #answerContainer></ng-template>
</mat-card-content>
</mat-card>
component.ts
@ViewChild('answerContainer', { read: ViewContainerRef }) answerContainer: ViewContainerRef;
private stepAnswerType1: ComponentFactory<StepAnswerType1Component>;
private stepAnswerType2: ComponentFactory<StepAnswerType2Component>;
private stepAnswerType3: ComponentFactory<StepAnswerType3Component>;
/* ... */
changeStep(id: number) {
if (this.step.type == 1) {
componentRef = this.answerContainer.createComponent(this.stepAnswerType1);
}
if (this.step.type == 2) {
componentRef = this.answerContainer.createComponent(this.stepAnswerType2);
}
if (this.step.type == 3) {
componentRef = this.answerContainer.createComponent(this.stepAnswerType3);
}
}
What could be the problem?
Fixed I updated part of the code. component.ts
import { StepAnswerType1Component } from './step-answer-type1/step-answer-type1.component';
import { StepAnswerType2Component } from './step-answer-type2/step-answer-type2.component';
import { StepAnswerType3Component } from './step-answer-type3/step-answer-type3.component';
/* some code */
@ViewChild('answerContainer', { read: ViewContainerRef }) answerContainer: ViewContainerRef;
/* some code */
changeStep(id: number) {
let componentRef, componentFactory;
if (this.step.type == 1) {
componentFactory = this.componentFactoryResolver.resolveComponentFactory(StepAnswerType1Component);
}
if (this.step.type == 2) {
componentFactory = this.componentFactoryResolver.resolveComponentFactory(StepAnswerType2Component);
}
if (this.step.type == 3) {
componentFactory = this.componentFactoryResolver.resolveComponentFactory(StepAnswerType3Component);
}
componentRef = viewContainerRef.createComponent(componentFactory);
}
Upvotes: 0
Views: 2487
Reputation: 9764
Make sure you are calling this method 'changeStep' inside 'ngAfterViewInit()'.
Upvotes: 1