Home > Mobile >  Cannot read properties of undefined (reading 'nativeElement')
Cannot read properties of undefined (reading 'nativeElement')

Time:10-19

Lets say i have two component parent and child and I'm trying to access the DOM element of Child component from parent component. But i'm facing issue of undefined native element.

export class ChildComponent implements OnInit,AfterViewInit{
   @ViewChild('pdfData', { read: ElementRef }) domData: ElementRef;
   constructor()
   ngOnInit(): void {
    some code..
  }
  ngAfterViewInit(): void {
    this.domData.nativeElement;
  }
}

Child component DOM element

<div #pdfData >
    <table *ngFor="let hubxReport of hubxReportList; let i=index">
      <tr>
        <th>{{hubxReport.categoryName}}   "Test"</th>
      </tr>
      <tr>
        <th>{{column}}</th>
      </tr>
      <tr *ngFor="let item of hubxReport.hubxDataItems">
        <td></td>
        <td>{{item.itemTitle}}</td>
        <td>{{item.itemValue}}</td>
        <td>{{item.itemUnit}}</td>
        <td>{{item.normalRange}}</td>
      </tr>
    </table>
</div>

And below code is Parent component and I'm trying to access Child component DOM element and the issue comes here.

export class ParentComponent implements OnInit,AfterViewInit{
@ViewChild('pdfData',{ read: ElementRef }) pdf: ChildComponent ;
constructor()
ngOnit(): void{
some code...
}
ngAfterViewInit() {
    this.pdf.domData.nativeElement;
    console.log(this.pdf.domData.nativeElement) //undefine here
  }
downloadPDF(isSubmit:any) {  
    debugger      
    let doc = new jsPDF();
    let rows: Array<any> = [];
    let header: Array<any> = [];
    let medicineInfo: any;
    let physicianInfo: any;
    //this.isShow = true;
    //this.changeRef.detectChanges();
    let content= this.pdf.domData.nativeElement; //undefine here
    let _elementHandlers =  
    {  
      '#editor':function(element,renderer){  
        return true;  
      }  
    };  
    doc.html(content.innerHTML,{  
            callback: function (doc) {
              doc.save();
            },
            x: 10,
            y: 80,
            // 'x': 15,
            // 'y': 15,
            width:190,  
            'elementHandlers':_elementHandlers  
          }); 
}

And here is my Stackblitz Link

CodePudding user response:

you "pdfData" template reference variable belongs to "child", so you can not access using viewChild from "parent"

You can in parent

<div >
  <!--in click button you pass a template reference variable of the child-->
  <button ...  (click)="downloadPDF(child,false)" >
    Print
  </button>
  <!--see that you use a template reference variable in child-->
  <my-child #child></my-child>
</div>

Your function downloadPDF

downloadPDF(child:any,isSubmit: any) {
    ....
    let content = child.domData.nativeElement; //see how access to the property
                                               //domData of the "child"
                      //yes, by defect all the variables in Angular are public
                      //include the variables that makes reference
                      //to viewChild
    ...
}

See your forked stackblitz

NOTE: You should use "const" (not let) when declare a variable that has no change, e.g., better const content=.. than let content=...

CodePudding user response:

In your stackblitz you are not using my-child element at all.

You can try accessing pdfData in child and then that variable in the parent.

So, domData is a variable declared in the child that reads from pdfData so it only exists and is accessible from the child. Since pdfData does not exist on your parent, reading it with ViewChild from here will return undefined, so you have to declare domData in the child.

You can, however, access the html variable in the child with ViewChild and assing it to a component variable (just like you are trying to do on the parent).

Then, on the parent you could <my-child #myChild></my-child> and

ViewChild('myChild', read: ChildComponent) myChildComponent.

This should give you access to all child properties, including the pdfData that comes from the child's ViewChild in the child (words are confusing)

myChildComponent.pdfData.nativeElement on AfterViewInit

The forked stackblitz

  • Related