0

How can you dynamically create a component on ngOnInit()?

I'm getting an error of "Cannot read property 'clear' of undefined" when I'm creating the component on the ngOnInit.

Here is my component:

import { Component, OnInit, ViewChild, ViewContainerRef, ComponentFactoryResolver, ComponentRef, ComponentFactory } from '@angular/core';
import { SpinnerService } from '../../tools/spinner/spinner.service';
import { CardService } from './card.service';
import { CardDatagridComponent } from './card-datagrid/card-datagrid.component';

@Component({
  selector: 'app-card',
  templateUrl: './card.component.html',
  styleUrls: ['./card.component.scss']
})
export class CardComponent implements OnInit {
  @ViewChild("cardDataGridContainer", { read: ViewContainerRef }) container;
  public renderReady: boolean = false;
  public componentRef: ComponentRef<any>;
  public selectedStatus = 'A';

  constructor(private spinner: SpinnerService, private cardService: CardService, private resolver: ComponentFactoryResolver) { }

  ngOnInit() {
    this.spinner.show();
    setTimeout(() => {
      this.spinner.hide();
      this.renderReady = true;
    }, 2000);
    this.selectTabStatus(this.selectedStatus);
  }

  selectTabStatus(status) {
    this.selectedStatus = status;
    this.createComponent(status);
  }

  createComponent(status) {
    this.container.clear();
    const factory: ComponentFactory<any> = this.resolver.resolveComponentFactory(CardDatagridComponent)
    this.componentRef = this.container.createComponent(factory);
    this.componentRef.instance.cardStatus = status;
  }

  ngOnDestroy() {
    this.componentRef.destroy(); 
  }
}

Any suggestion guys? Thanks!

Juan
  • 429
  • 3
  • 6
  • 19
  • Check here: https://stackoverflow.com/questions/38888008/how-can-i-use-create-dynamic-template-to-compile-dynamic-component-with-angular And here: https://blog.angularindepth.com/here-is-what-you-need-to-know-about-dynamic-components-in-angular-ac1e96167f9e And also here (v6):https://angular.io/api/core/ComponentFactoryResolver – monstertjie_za May 22 '18 at 10:08

1 Answers1

0

AngularJS !== Angular, you should remove the tag. And perhaps add "Typescript"

anyway here I accomplished to do what you're looking for

Blitz

In Angular4+ Renderer2 was added so:

import {Renderer2, ElementRef} from "@angular/core";

constructor(private targetEl: ElementRef, private renderer: Renderer2) {

    this.$matCard = this.renderer.createElement('mat-card');

    const matCardInner = this.renderer.createText('Dynamic card!');
    this.renderer.appendChild(this.$matCard, matCardInner);
    const container = this.targetEl.nativeElement;
    this.renderer.appendChild(container, this.$matCard);
}
Sampgun
  • 2,822
  • 1
  • 21
  • 38
  • Why not instead of just pointing to code, paste the core functionality here, and give a brief explanation, so that anyone else looking for this in the future, can understand something, instead of just copying and pasting – monstertjie_za May 22 '18 at 10:11