1

I am adding an event listener to a button inside of an object method. I am attempting to add a call to another method function but when I use this.reset() the 'this' points to the listener//button rather than the object itself.

This code has been refactored into an object and was working fine before. In that case I didn't need to use 'this'.

const colorGame = {
    reset: function() {...},

    init: function() {
        for (let i = 0; i < modeSwitches.length; i++) {
            modeSwitches[i].addEventListener("click", function() {
                modeSwitches[0].classList.remove('selected');
                modeSwitches[1].classList.remove('selected');

                // These two lines are why I can't use anonymous functions
                this.classList.add('selected'); 
                this.textContent === 'Easy' ? numSquares = 3 : numSquares = 6;
                this.reset();
            });
        }

        ...
    resetButton.addEventListener('click', function() {
            this.reset(); // This call also fails with the same error
});

Error in Chrome browser console : colorGame.js:78 Uncaught TypeError: this.reset is not a function

My intent is to use colorGame.reset() and have that called when the buttons are clicked.

3 Answers 3

2

Have your colorGame object implement the EventListener interface by giving it a handleEvent method. Then you can bind the object itself as the event handler, and its handleEvent method will be invoked when an event takes place.

The value of this in handleEvent will be the colorGame object.

const colorGame = {
  handleEvent: function(event) {
    // handle events here
    switch (event.type) {
      case "click":
        this.reset();
        break;
        
      default:
        console.log("unhandled event type");
    }
  },

  reset: function() {
    console.log("reset was called");
  },

  // Bind the colorGame object instead of binding functions
  init: function() {
    for (let i = 0; i < modeSwitches.length; i++) {
      modeSwitches[i].addEventListener("click", colorGame);
    }

    resetButton.addEventListener('click', colorGame);
  }
}

Sign up to request clarification or add additional context in comments.

3 Comments

Is the handleEvent method special in such a way as to allow the addEventListener() to bind to it rather than a function? I thought the second parameter for addEventListener() was a function.
Yes, you can pass any regular object instead of a function if the object has (or inherits) a method named handleEvent.
simply, this is a great solution.
2

Change your event listeners to use anonymous functions like: modeSwitches[i].addEventListener("click", () => this.reset()); resetButton.addEventListener('click', () => this.reset());

2 Comments

That is one way my code has been however since I am also using 'this' to refer to the event listener I'd lose those parts too. Editing original to show.
@twodox: Then you'd just use define an event parameter and use event.currentTarget, which references the element. You'd do the same on my answer too. Using var that = this; is almost unheard of in modern JS. It was an unfortunate practice that we've moved beyond. Not sure why it still gets suggested as a good solution.
1

Simply store this into another variable. I usually call it that.

const colorGame = {
reset: function() {...},

init: function() {

    let that = this;
    for (let i = 0; i < modeSwitches.length; i++) {
        modeSwitches[i].addEventListener("click", function() {
            ...
            that.reset();
        });
    }
    ...
    resetButton.addEventListener('click', function() {
        that.reset(); 
    });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.