D Dimitrov
D Dimitrov

Reputation: 115

Angular/Typescript call a class method in an event

I am totals new to TS and Angular and I am trying to build a simple drawing component on a canvas. I have so far worked my way to a point where I totally don't know what I am doing. The different "this" in Ts was a BIG issue for me, but I think I get it now. Here is my code:

import { Component, OnInit } from '@angular/core';

@Component({
    selector: 'track-creator',
    templateUrl: 'track-creator.component.html',
    styleUrls: ['track-creator.component.css']
})

export class TrackCreatorComponent implements OnInit {
    public canvas;
    public context;

    ngOnInit(): void {
        this.canvas = document.getElementById('trackCreatorCanvas');
        this.context = this.canvas.getContext("2d");

        this.canvas.addEventListener("mousedown", function (e) {
            this.draw(e);
        }, false);
    }

    draw(e): void{
        this.context.beginPath();
        this.context.arc(e.clientX,e.clientY,5,0,2*Math.PI);
        this.context.stroke();
    }
}

The error here is:

ERROR TypeError: this.draw is not a function

I have done some reading on TS, but I still cant understand what to do in this situation. I'm not retarded (not too much at least), but I don't know much about TS. Please have this in mind when you try to explain me my error.

Upvotes: 1

Views: 6152

Answers (2)

eyoeldefare
eyoeldefare

Reputation: 2303

Why are you calling a drawing function inside an .addEventListener method? That is supposed to be listening to the mousedown not drawing on the canvas. You are supposed to give it an x and y cordinate there based on e. Not draw there.

Here some example:

import { Component, OnInit} from '@angular/core';

 @Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})


export class AppComponent implements OnInit{
   public canvas;
   public context;
   public mous ={x:undefined,y:undefined}

ngOnInit(){
   this.canvas = document.querySelector("canvas");
   this.context = this.canvas.getContext("2d");
   this.canvas.width = window.innerWidth;
   this.canvas.height = window.innerHeight;
   this.canvas.addEventListener("mousedown", function (e) {
        this.mous.x=e.x; //getting the cordinates x
        this.mous.y=e.y; //getting the cordinates y

    }, false);
     this.draw(this.mous.x,this.mous.y)

}

//you can improve this but you can change it like this 
draw(x,y){
    this.context.beginPath();
    this.context.arc(x, y, 5, 0, Math.PI * 2, false);
    this.context.fillStyle ="black";
    this.context.fill();
}

}

The draw() method is not doing anything nor listen.

Upvotes: 0

S.V.
S.V.

Reputation: 1221

Instead of this:

this.canvas.addEventListener("mousedown", function (e) {
    this.draw(e);
}, false);

try writing this:

this.canvas.addEventListener("mousedown", (e) => {
    this.draw(e);
}, false);

When you create a new function without a lambda expression, this refers to the context of that function. The lambda expression preserves the context of this

Try going console.log(this) in the first example and do it again in the second example to get a clearer view of what this means.

Upvotes: 9

Related Questions