2

I have a class with some variables and a function with call to an function from an external library this function requires a callback like so:

class UserGestures {

    private gestureManager : HammerManager;
    private gestureDetected : string;

    constructor() {

        this.gestureManager = new Hammer.Manager(document.body);
        this.detectOnElement.addEventListener('touchend', this.resetGestures);
        this.gestureDetected = "OUTER";

        this.startDetection();
    }

    private startDetection() {

        this.gestureManager.on('pinch rotate pan', (e : HammerInput) => {

            console.log(this.gestureDetected);

            if(this.gestureDetected === "OUTER") {
                console.log("checking for new gesture");
                this.gestureDetected = "INNER";
            }
        });
    }

    private resetGestures() {
        console.log("reset");
        this.gestureDetected = "OUTER";
        console.log(this.gestureDetected);
    }
}

The problem i am having is when i run this code for the first time. And the event from this.gestureManager.on('pinch rotate pan', (e : HammerInput) => {} fires I see the following console.logs in the following order:

OUTER
checking for new gesture
INNER

Now when the resetGestures function fires I see the following:

reset
OUTER

This is all as expected. But now comes the problem...
When The this.gestureManager.on('pinch rotate pan', (e : HammerInput) => {} fires again I see the following console.logs:

INNER

Instead of the expected:

OUTER
checking for new gesture
INNER

Why is this happening? What I think is happening is that the callback is storing the value of this.gestureDetected locally and not checking it at the class level where it is defined. How do I fix this?

FYI This is reduced code. But After extensive testing this is what it boils down to (99% sure)

FutureCake
  • 2,614
  • 3
  • 27
  • 70

1 Answers1

0

Instead of this:

this.detectOnElement.addEventListener('touchend', this.resetGestures);

Do this:

this.detectOnElement.addEventListener('touchend', () => this.resetGestures());

Otherwise, this won't refer to the object you're thinking of. More about this JavaScript behavior here: https://thenewstack.io/mastering-javascript-callbacks-bind-apply-call/

You can also explicitly bind the this parameter:

this.detectOnElement.addEventListener('touchend', this.resetGestures.bind(this));

More info and explanation also on this answer.

Jean-Philippe Pellet
  • 59,296
  • 21
  • 173
  • 234