I'm getting this error in runtime on my Angular 13 Ionic 6 application when run on two Android devices (Samsung Galaxy A32 and Xiaomi Rednote 8).
ERROR Error: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'getContext')
Instead of in ngAfterViewInit
, I tried to instantiate everything in ngOnInit
(with {static: true }
) but it did not help.
This canvas is implemented in the whiteboard.component which is embedded in the chat.page.
What am I missing?
whiteboard template:
<ion-grid >
<ion-row>
<ion-col>
<canvas #canvas
(mousedown)="startDrawing($event)"
(touchstart)="startDrawing($event)"
(touchmove)="moved($event)"
(mousemove)="moved($event)"
(mouseup)="endDrawing()"
(touchend)="endDrawing()">
</canvas>
</ion-col>
</ion-row>
...
whiteboard controller:
import { Component, ViewChild, AfterViewInit, ElementRef, OnInit } from '@angular/core';
import { NavController, IonContent } from '@ionic/angular';
import { Platform, ToastController } from '@ionic/angular';
import { AwsFileUploadService } from '../../services/aws-file-upload.service'
@Component({
selector: 'app-whiteboard',
templateUrl: './whiteboard.component.html',
styleUrls: ['./whiteboard.component.scss'],
})
export class WhiteboardComponent implements AfterViewInit {
@ViewChild('canvas', { static: false })
imgToast: HTMLElement; //For image hover capture
//canvas: ElementRef<HTMLCanvasElement>;
private canvas: ElementRef<HTMLCanvasElement> = {} as ElementRef<HTMLCanvasElement>;
private ctx: CanvasRenderingContext2D;
canvasElement: any;
ngAfterViewInit() {
this.ctx = this.canvas.nativeElement.getContext('2d'); // <<----- ERROR HERE
this.ctx.canvas.width = this.plt.width() ;
this.ctx.canvas.height = this.plt.height();
//Need to upload the initial problem image here
//Handle image hover if needed - set id of html image element to imgSection
this.imgToast = document.getElementById('imgSection');
this.imgToast.addEventListener('mousemove', ev => {
this.showToastOnImage();
});
}
...
chat page template:
<ion-header>
<ion-toolbar>
<ion-title>chat</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-grid >
<ion-row >
<ion-col size="12" id="content-text" style="height: 60%">
<app-whiteboard style="height: 100%; width: 100%"></app-whiteboard>
</ion-col>
...
chat page module:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { FIREBASE_OPTIONS } from '@angular/fire/compat';
import { IonicModule } from '@ionic/angular';
import { environment } from '../../environments/environment';
import { ChatPage } from './chat.page';
import { WhiteboardComponent } from './whiteboard/whiteboard.component';
import { RouterModule } from '@angular/router';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
RouterModule
],
declarations: [ChatPage, WhiteboardComponent],
providers: [{ provide: FIREBASE_OPTIONS, useValue: environment.firebaseConfig }],
exports: [ChatPage]
})
export class ChatPageModule {}
CodePudding user response:
As @ChrisHamilton refers, you have to add @ViewChild
just before the canvas
.
export class WhiteboardComponent implements AfterViewInit {
imgToast: HTMLElement; //For image hover capture
@ViewChild('canvas', { static: false }) canvas: ElementRef<HTMLCanvasElement>;