I am Trying to make a shared download as pdf method in my service file. But when i try to call my method in my app component it gives ‘Cannot read properties of undefined (reading ‘nativeElement’)’ error. The Download method works perfectly when I call it directly in my app component.
#here is my download.service.ts#
import { Injectable, ElementRef, ViewChild } from '@angular/core';
declare var require: any;
import * as pdfMake from "pdfmake/build/pdfmake";
import * as pdfFonts from "pdfmake/build/vfs_fonts";
import { Observable } from 'rxjs';
const htmlToPdfmake = require("html-to-pdfmake");
(pdfMake as any).vfs = pdfFonts.pdfMake.vfs;
@Injectable({
providedIn: 'root'
})
export class DownloadService {
@ViewChild('pdfTable')
pdfTable!: ElementRef;
constructor() { }
public downloadpdf() {
const pdfTable = this.pdfTable.nativeElement;
var html = htmlToPdfmake(pdfTable.innerHTML);
const documentDefinition = { content: html };
pdfMake.createPdf(documentDefinition).download();
}
}
#here is my download call function in my login.component.ts#
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { Router } from '@angular/router';
import { MsalService } from '@azure/msal-angular';
import html2canvas from 'html2canvas';
import { DownloadService } from 'src/app/services/download.service';
// import { ExportAsConfig, ExportAsService } from 'ngx-export-as';
declare var require: any;
import * as pdfMake from "pdfmake/build/pdfmake";
import * as pdfFonts from "pdfmake/build/vfs_fonts";
const htmlToPdfmake = require("html-to-pdfmake");
(pdfMake as any).vfs = pdfFonts.pdfMake.vfs;
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
public logindet: FormGroup
public UN:string
@ViewChild('pdfTable')
pdfTable!: ElementRef;
constructor(
private router: Router,
private msalservice:MsalService,
private ds: DownloadService
) { }
ngOnInit(): void {
}
downloadAsPDF(){
this.ds.downloadpdf()
}
}
>Solution :
I would suggest to remove the ViewChild located inside your service and to add an addtional parameter to your downlodpdf method of type ElementRef. So you could pass necessarry ElementRefs to the service directly.
download.service.ts
public downloadpdf(elementRef: ElementRef) {
const nativeElement = elementRef.nativeElement;
const html = htmlToPdfmake(nativeElement.innerHTML);
const documentDefinition = { content: html };
pdfMake.createPdf(documentDefinition).download();
}
login.component.ts
downloadAsPDF(){
this.ds.downloadpdf(this.pdfTable);
}