Lets say I have two component: "UserPatientsReportFormComponent" and "UserPatientsReportFormTemplateComponent". I want to call "UserPatientsReportFormTemplateComponent" temaplate id to "UserPatientsReportFormComponent". I'll share the code below and please let me know the changes I needed to achieve it
This below template code is from "UserPatientsReportFormTemplateComponent" component
<div >
<table id="pdfData" #pdfData *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 i want to call the above template here "UserPatientsReportFormComponent"
@ViewChild('pdfData') pdfData: ElementRef;
and I'm trying to access the template Id in this below function
downloadPDF(isSubmit:any) {
debugger
let doc = new jsPDF();
let rows: Array<any> = [];
let header: Array<any> = [];
let medicineInfo: any;
let physicianInfo: any;
let content=this.pdfData.nativeElement; //--<<here im calling the template id>>--
let _elementHandlers =
{
'#editor':function(element,renderer){
return true;
}
};
doc.fromHTML(content.innerHTML,15,15,{
'width':190,
'elementHandlers':_elementHandlers
});
Currently I get an error that says Cannot read properties of undefined (reading 'nativeElement')
CodePudding user response:
From your explanation, this is what your components hierarchy looks like:
<app-user-patients-report-form>
<app-user-patients-report-form-template>
<table #pdfData>
<!-- ... -->
</table>
</app-user-patients-report-form-template>
</app-user-patients-report-form>
You are trying to call the pdfData
element (which is a child of UserPatientsReportFormTemplateComponent
) as if it's a direct child of UserPatientsReportFormComponent
. This will not work.
Instead, put this line:
@ViewChild('pdfData') public pdfData: ElementRef;
inside the actual component that contains pdfData
which in your case is UserPatientsReportFormTemplateComponent
class.
To access that element from UserPatientsReportFormComponent
, first you need to see your direct child UserPatientsReportFormTemplateComponent
via the same @ViewChild
way as follows:
class UserPatientsReportFormComponent {
@ViewChild(UserPatientsReportFormTemplateComponent) userPatientReportFormTemplate: UserPatientsReportFormTemplateComponent;
}
Then, inside your downloadPDF
function, you can try accessing the template as follows:
downloadPDF() {
// ...
let content = this.userPatientReportFromTemplate?.pdfData?.nativeElement;
// ...
}
Careful
You are accessing children via the @ViewChild
decorator, which are not usually available until the component view is initiated (happens inside ngAfterViewInit
lifecycle method). Make sure you are executing the downloadPDF
method when both components' views are initialised.
CodePudding user response:
You can't directly access the nephew of your current component, but you can emit from your component the nativeElement
.
UserPatientsReportFormTemplateComponent
@Output() pdfDataEmitter: EvenetEmitter<HTMLElement> = new EventEmitter();
@ViewChild('pdfData') set pdfData(element: ElementRef) {
this.pdfDataEmitter.emit(element.nativeElement);
}
AppUserPatientsReportForm
private _pdfDataNativeElement: HTMLElement;
set pdfDataElement(element: HTMLElement) {
this._pdfDataNativeElement = element
}
get pdfDataElement(): HTMLElement {
return this._pdfDataNativeElement;
}
<app-user-patients-report-form-template (pdfDataEmitter)="pdfDataElement = $event">
</app-user-patients-report-form-template>
In this way, you are setting your #pdfElement to his parent without direct access to it. I prefer this way because you can handle the information instead of having direct access to his property.