0

I try to call a dynamic component from another component but it showing me an empty page

This is the dynamic component.ts :

@Component({

selector: 'app-draw-linechart',
templateUrl: './draw-linechart.component.html',
styleUrls: ['./draw-linechart.component.css']
})
export class DrawLinechartComponent implements OnInit {
 constructor(private productservice: ProductService) {}

ngOnInit() {
     this.PrepareData(); }     
PrepareData() {
  this.productservice.getProductsData(this.productHistoric).subscribe((data) => {
     this.historicproducts = data;
     console.log("historic products", this.historicproducts)
  });}

The dynamic component.html :

 <div class="container">
<mat-grid-list cols="1" rows="2" rowHeight="100px"  >
 <mat-grid-tile>
   <mat-card class="dashboard-card">
    <mat-card-header>
      <mat-card-title>
        Line chart
      </mat-card-title>
    </mat-card-header>
  <mat-card-content class="dashboard-card-content">
    <button mat-raised-button color="warn" (click)="prepareData()">Add Line chart</button>
  </mat-card-content>
</mat-card>

This is the other component where I called the dynamic component:

export class LineChartComponent implements OnInit{
constructor(private componentFactoryResolver:ComponentFactoryResolver,private vf:ViewContainerRef){}
...
OnSubmit(){
 this.createComponent();}

createComponent(){
 let resolver = this.componentFactoryResolver.resolveComponentFactory(DrawLinechartComponent);
 this.vf.createComponent(resolver);

} Then I added the dynamic component in entryComponent of the module.ts:

entryComponents:[DrawLinechartComponent]

In the console I got the correct data but I had an empty page ( I don't know why it not reading the html code )

1
  • do you have a host to put the component in it? Commented Jun 29, 2020 at 17:02

1 Answer 1

2

first, create a directive, you use this directive to any element that you want to be a container for your dynamic component:

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[ad-host]',
})
export class AdDirective {
  constructor(public viewContainerRef: ViewContainerRef) { }
}

in your template:

<ng-template ad-host></ng-template>

in your component:

@ViewChild(AdDirective, {static: true}) adHost: AdDirective;

and then in your function:

const viewContainerRef = this.adHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent(componentFactory);

now your component will be created in the ng-template tag.

you can see a detailed example in angular docs

Sign up to request clarification or add additional context in comments.

5 Comments

It's a nice solution but my problem is I had in the component where I must call the dynamic component a dialog form So now with your solution the dynamic component appear but inside the form ! This is the html I had <mat-dialog-content> <form [formGroup]="lchartForm">... <button mat-raised-button color="primary" class="btn btn-success btn-lg btn-block" type="submit" (click)="OnSubmit();createComponent()" [mat-dialog-close]="true">Submit</button> <ng-template ad-host></ng-template>
oh. if you want to open a dialog you don't need to handle the creating of a component manually. mat dialog handles it for you.
In fact I want the dynamic component appear when I click on submit in the other component
ok just put the <ng-template ad-host></ng-template> in the parent component, then when the user submits and closes the dialog load the dynamic component;
what ever hteml you have in your dynamic template will be placed in <ng-template> so wherever it is the dynamic component will load there

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.