I'm encountering this issue only in Firefox browser, not in Chrome. I'm attempting to obtain the nativeElement
for the gridster
element.
I am using angular-gridster2 v17.0.0
In my HTML :
<gridster
[options]="options"
#gridsterContainer>
<gridster-item
*ngFor="let dis of displayList; let i = index"
[item]="dis.layout">
<dis-data></dis-data>
</gridster-item>
</gridster>
In my component, I've defined a ViewChild
and trying to access nativeElement
in my download
event:
@ViewChild('gridsterContainer', { static: false }) gridsterContainer: ElementRef;
downloadPDF() {
setTimeout(() => {
const content = this.gridsterContainer.nativeElement;
const marginHeight: number = 40;
const width = content.clientWidth;
const height = content.scrollHeight + marginHeight;
let orientation: 'p' | 'portrait' | 'l' | 'landscape' = 'l';
if (width > height) {
orientation = 'l';
} else {
orientation = 'p';
}
domToImage.toPng(content, {
width: width,
height: height
})
.then((imageBase64) => {
const img = new Image();
img.src = imageBase64;
img.onload = () => {
const cursorPositionX = 25;
let cursorPositionY = 75;
const jsPdfOptions: jsPDFOptions = {
orientation: orientation,
unit: 'pt',
format: [width + 50, height + 220]
};
const pdf = new jsPDF(jsPdfOptions);
pdf.addImage(imageBase64, 'PNG', cursorPositionX, cursorPositionY += 20, width, height);
pdf.save('Jack_Test.pdf');
};
img.onerror = (error) => {
console.error('Error loading image:', error);
};
})
.catch((error) => {
console.error('Error converting to image:', error);
});
}, 10);
}
However, content is showing as undefined. I've tried using ngAfterViewInit
and document.querySelector('gridster')
as well, but I'm unable to retrieve the nativeElement.
The issue occurs because gridsterContainer
doesn't really contain an ElementRef
. By default, @ViewChild()
reads the instance of the Component. If it's not an Angular component but a native HTML element, Angular reads the ElementRef
. However in this particular case, Angular will read the component instance by default, as <gridster>
is an Angular component. To read the element ref, you need to tell Angular to do so by using the read
parameter:
@ViewChild('gridsterContainer', { read: ElementRef }) gridsterContainer: ElementRef;
Unfortunately, Angular is not smart enough to warn you about the wrong type being used. This will likely be improved with the new signal-based queries, however as of July 2024 they are in developer preview and should be used with caution.
Further reading: https://angular.dev/api/core/ViewChild?tab=description