matchifang
matchifang

Reputation: 5450

ViewContainerRef is undefined when called in ngAfterViewInit

I want to dynamically create a child component when the parent component is initialised, but when I tried to create it in ngAgterViewInit(), it throws the error that the ViewContainerRef is undefined.

component.ts

  @ViewChild('container', {read: ViewContainerRef}) container: ViewContainerRef;

  constructor(private resolver: ComponentFactoryResolver) {
  }

  ngAfterViewInit(){
    const factory = this.resolver.resolveComponentFactory(ChildComponent);
    this.container.createComponent(factory); //container is undefined here

  }

component.html

...
<div class="row" #container ></div>
...

Upvotes: 2

Views: 4887

Answers (1)

Martin Parenteau
Martin Parenteau

Reputation: 73751

Since the div is inside an ngIf conditional block, it may not be available in ngAfterViewInit. You can protect the code against that possibility by monitoring the presence of the element with ViewChildren and the QueryList.changes event:

@ViewChildren('container', { read: ViewContainerRef }) containers: QueryList<ViewContainerRef>;

ngAfterViewInit() {
  if (this.containers.length > 0) {
    // The container already exists
    this.addComponent();
  };

  this.containers.changes.subscribe(() => {
    // The container has been added to the DOM
    this.addComponent();
  });
}

private addComponent() {
  const container = this.containers.first;
  const factory = this.resolver.resolveComponentFactory(ChildComponent);
  container.createComponent(factory);
}

See this stackblitz for a demo.

Upvotes: 3

Related Questions