Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load dynamic component within *ngIf - createComponent is undefined

I'm trying to load a dynamic component into my view when a user clicks the button which looks like the following:

<button (click)="showContent()">Show Panel</button>
<!--This starts as 'showPanel = false'-->
<div *ngIf="showPanel">
    <ng-template #ref></ng-template>
</div>

However, when clicking the button in my view, I try to run loadComponent() but I get an error stating Cannot read property 'createComponent' of undefined

I've looked up some solutions to this, there were some suggesting using QueryList<ViewContainerRef> but I have not been successful in getting it to work.

Source: ViewContainerRef is undefined when called in ngAfterViewInit

Another solution suggested using ElementRef and checking the chaged state, but even that was always undefined when trying to check it in ngAfterViewInit.

Source: @ViewChild in *ngIf

I'm looking for options that will work with Angular 8, but I'm not entirely sure where to look next.

Code below:

parent.component.ts

export class ParentComponent {

@ViewChild('ref', { static: false, read: ViewContainerRef }) ref: ViewContainerRef;

showPanel = false;

loadComponent(): void {
    const factory = this.componentFactoryResolver.resolveComponentFactory(ChildComponent);
    const component = this.ref.createComponent(factory);
    component.changeDetectorRef.detectChanges();
}

showContent(): void {
    this.showPanel = !this.showPanel;
    this.loadContent(); // Error is thrown here, this doesn't make sense as *ngIf should now be true.
}
like image 551
expenguin Avatar asked Jun 23 '26 18:06

expenguin


1 Answers

It's because *ngIf removes the div element while the condition evaluates to false, it means that the child element doesn't exists inside your component template.

you can use [hidden] instead which only hide the div element so you can access it through template reference variable.

<button (click)="showContent()">Show Panel</button>
<!--This starts as 'showPanel = false'-->
<div [hidden]="!showPanel">
    <ng-template #ref></ng-template>
</div>
like image 182
Bilel-Zheni Avatar answered Jun 26 '26 15:06

Bilel-Zheni