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