tester
tester

Reputation: 3987

Class this when using Events

I have a JavaScript Class with some methods.
I also have a link with onclick and its function this does not point to the Class instance.

Unfortunately it doesn't recognize the inner Class Methods, maybe because this is not clear enough.

class MyJsClass {
    dummyFunc1() {
        $('#my-link').click(function() {
            console.log('test');
            this.dummyFunc2();
        });
    }
    
    dummyFunc2() {
        console.log('dummyfunc2');
        this.dummyFunc3();
    }
    
    dummyFunc3() {
        console.log('dummyfunc3');
    }
}

This doesn't work so I changed it a little bit like this, but it still doesn't work saying Cannot read property 'dummyFunc3' of undefined:

dummyFunc1() {
    var dummyfunc2 = this.dummyFunc2();
    $('#my-link').click(function() {
        console.log('test');
        dummyfunc2();
    });
}

Upvotes: 1

Views: 52

Answers (1)

Roko C. Buljan
Roko C. Buljan

Reputation: 206028

Inside jQuery methods/functions (like .click() etc) this has its own context of jQuery Object instance where this is the returned DOM Element.
Use instead an arrow function => since it does not have its own bindings to this - therefore making this refer to the desired Class instance:

1. Using Arrow Function

class MyJsClass {
  dummyFunc1() {
    $('#my-link').on("click", (evt) => {
      // If needed use evt.currentTarget instead of this
      // console.dir(evt.currentTarget);   // {}<div id="my-link" />
      this.dummyFunc2(); // this == MyJsClass instance
    });
  }

  dummyFunc2() {
    console.log('dummyfunc2');
    this.dummyFunc3();
  }

  dummyFunc3() {
    console.log('dummyfunc3');
  }
}

const MJSC = new MyJsClass();
MJSC.dummyFunc1();
<a id="my-link">CLICK ME</a>


<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

2. Using Function.prototype.bind

There's also the deprecated $.proxy if needed:

$('#my-link').on("click", $.proxy(this.dummyFunc2, this)); 

which from jQuery 3.3 can be better used with JS's Function.prototype.bind

class MyJsClass {
  dummyFunc1() {
    $('#my-link').on("click", this.dummyFunc2.bind(this));
  }

  dummyFunc2() {
    console.log('dummyfunc2');
    this.dummyFunc3();
  }

  dummyFunc3() {
    console.log('dummyfunc3');
  }
}

const MJSC = new MyJsClass();
MJSC.dummyFunc1();
<a id="my-link">CLICK ME</a>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

Upvotes: 3

Related Questions