1

Im making a program that dynamically creates html elements and when you click any of those elements it should display its value in another textbox. This is the class im using to define the element:

class msg_element{
  constructor(msg){
    this.message = msg;

    this.element = document.createElement("P");
    this.element.innerHTML = this.message;
    this.element.addEventListener("click", function(){
      document.getElementById("update").value = this.message;
    });

    document.getElementById("textview").appendChild(this.element);
  }
}

and this is the loop that creates the elements:

for(var i = 0; i < bmg_msg.length; i++){
    var element = new msg_element(bmg_msg[i]);
  }

it creates all the elements correctly, but the clicking function doesnt work, it just displays "undefined" in the textbox. What can I do to fix this?

2
  • can you show complete example of your code including html js and css? Commented Nov 17, 2019 at 17:19
  • 2
    The value of this inside the event listener won't be the same as this in the constructor function. You could use an => function instead of a regular function, or you could explicitly store this in a separate local variable in the constructor. Commented Nov 17, 2019 at 17:20

2 Answers 2

2

The line

    this.element.addEventListener("click", function(){
      document.getElementById("update").value = this.message;
    });

is the problem. When you create the callback you define it as function(){...}. The problem with that is that it causes this to refer to the event target. To fix this you can either:

Use an Arrow function so that this will refer to the current class instance.

    this.element.addEventListener("click", ()=>{
      document.getElementById("update").value = this.message;
    });

or create a variable to store the reference to the constructor

    let _this = this;
    this.element.addEventListener("click", function(){
      document.getElementById("update").value = _this.message;
    });
Sign up to request clarification or add additional context in comments.

4 Comments

this never refers to the function itself. In an event listener, it's the same as the event target.
"either do" I'd expand on this textually.
"lambda function" ? You mean Arrow function
PS, don't forget that Class is just syntactic sugar for prototypal inheritance.
1

In this portion of your code:

this.element.addEventListener("click", function(){
  document.getElementById("update").value = this.message;
});

Beware: this outside of the click handler is different from this inside of it.

Inside event handlers, this always points to the DOM element that fired the event (in your case it's the paragraph you're creating).

A possible fix would be to use a variable which will hold the value of this.message, e.g.:

var myMessage = this.message;
this.element.addEventListener("click", function(){
  document.getElementById("update").value = myMessage;
});

2 Comments

" this always points to the DOM element that fired the event" is not entirely true, it depends on the context of this.
@RokoC.Buljan What do you mean? In what cases does it not point to the event target?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.