1

I've created a class and I'm trying to call a method from inside that class from another method inside that same class. I've seen online that some people say use 'this' keyword, but as you can see from the example, that doesn't work. Can someone please explain in simple terms how to call a class method from inside another method in that same class? Thanks!

class Form {
  constructor() {
  }
  fn1 () {
    console.log('fn1 calling fn2 now:')
    this.fn2();
  }

  fn2 () {
    console.log('fn1 called me')
  }
}

let myForm = new Form();
myForm.fn1();

Example can be found here

The error I keep getting is this: Uncaught TypeError: this.fn2 is not a function

James Bradley
  • 115
  • 2
  • 11
  • 1
    Why not simply log `this` to find out what its value is? – Sebastian Simon Aug 01 '19 at 21:00
  • FYI, the code you show embedded into your question does not illustrate the problem - that code would work just fine. It's more involved than that - related to the `.addEventListener()` callback that can be seen in the linked code. – jfriend00 Aug 01 '19 at 21:16
  • The code you posted here *does* work. Please post the real code that must be different in the way you are calling `fn1()`. – Bergi Aug 01 '19 at 21:50

1 Answers1

4

There's nothing wrong with the code you show embedded into your question - that should work just fine. The issue arises when you pass a method to .addEventListener() as a callback (which shows in the code you have a link to).

Change this:

document.getElementById('call-func').addEventListener('click', this.fn1);

to this:

document.getElementById('call-func').addEventListener('click', this.fn1.bind(this));

The problem is that passing this.fn1 loses the value of this so when the listener calls the callback later, the object that it belongs to is lost and then this inside of fn1() is wrong. In addition, .addEventListener() explicitly sets the this value to the DOM element that triggered the event (which is not your object).

The same thing would happen if you did this:

let f = this.fn1;
f();

Using .bind(this) rebinds the value of this when the listener calls it.


FYI, you could also do it this way with a fat-arrow function:

document.getElementById('call-func').addEventListener('click', () => this.fn1());

Or, an older way of doing it:

var self = this;
document.getElementById('call-func').addEventListener('click', function() {
    self.fn1();
});

My preference is to use .bind(this).


More explanation on event listeners and this here: "This" within es6 class method

More explanation on the general concept of how this gets set when a function is called here: When you pass 'this' as an argument

jfriend00
  • 580,699
  • 78
  • 809
  • 825