Home > Net >  Angular 14 ERROR TypeError: Cannot read properties of undefined (reading 'createComponent'
Angular 14 ERROR TypeError: Cannot read properties of undefined (reading 'createComponent'

Time:11-09

I have a header component. In header component I want to create header-user-menu component dynamically when user logged in. But I get error. In header template, I have added both dynamic and static components in order to check if there is a problem with the template but static component works on the other hand dynamic component does not work

header.component.ts

export class HeaderComponent implements OnInit, OnDestroy, AfterViewInit {
  private dynamicHeaderUserMenu: ViewContainerRef;
  @ViewChild('appHeaderUserMenu', { read: ViewContainerRef, static: true }) set appHeaderUserMenu(
    vcRef: ViewContainerRef
  ) {
    if (vcRef) {
      this.dynamicHeaderUserMenu = vcRef;
    }
  }

ngAfterViewInit(): void {
    //initialize dynamic components
    this.subs.push(
      this.isLoggedIn$.subscribe((loggedIn) => {
        if (loggedIn) {
          const createRef = this.dynamicHeaderUserMenu.createComponent(HeaderUserMenuComponent);
        }
      })
    );
  }

header.component.html

<div *ngIf="showUMenu" f>
    <app-header-user-menu></app-header-user-menu>
    <ng-template #appHeaderUserMenu></ng-template>
</div>

The error is as below ERROR TypeError: Cannot read properties of undefined (reading 'createComponent')

CodePudding user response:

vcRef is not defined in the constructor. Since you declared as static, it will get instanciated at ngOnInit at best.

So try moving the code of your constructor into your ngAfterViewInit function, or in a new ngOnInit function.

export class HeaderComponent implements OnInit, OnDestroy, AfterViewInit {

  @ViewChild('appHeaderUserMenu', { read: ViewContainerRef, static: true }) 
  vcRef!: ViewContainerRef;

  ngAfterViewInit(): void {
    //initialize dynamic components
    this.subs.push(
      this.isLoggedIn$
        .pipe(filter(v => !!v), first())
        .subscribe((loggedIn) => {
          if (loggedIn) {
            const createRef = this.vcRef.createComponent(HeaderUserMenuComponent);
        }
      })
    );
  }
  • Related