Shouvik Shouvik - 4 months ago 10
Javascript Question

Pass separate scope in each new Instance created in ES6

I have written some code as below. Here I am creating new instances for the class

todos
and passing separate text each time to the constructor.

inside
setText
i am binding a click method to the element
test
so that it returns its the text associated with it on click of it.

Problem here is, the three components created by this method has separate texts displayed but on click of any element it displays the text as
'this is a todo component3'
which is the last text i passed into the constructor. I want it to be separate for each component. Please help.

class todos{
constructor(text){
this.istodo = false;
this.text = text;
}
_changestatus(){
this.istodo = !this.istodo;
}
setText(){
this.getDiv = document.getElementById('test');
this.getDiv.innerHTML = this.getDiv.innerHTML+'\n'+this.text;
this.getDiv.onclick = (event)=> {alert(this.text)}; //this is always coming as "this is a todo component3"
}
}


let todo = new todos('this is a todo component');
todo.setText();
let todo1 = new todos('this is a todo component1');
todo1.setText();
let todo2 = new todos('this is a todo component2');
todo2.setText();
let todo3 = new todos('this is a todo component3');
todo3.setText();

Answer

The problem is that you have only one container for all your texts and every next todo you add overwrites onclick handler created by previous one. So this is the problem.

To solve it you just need to make sere every todo crates it's one container for the text. Here is one possible way to do it. Note, that document.getElementById('test') from the code.

    class todos {
      constructor(text) {
        this.istodo = false;
        this.text = text;
      }
      _changestatus() {
        this.istodo = !this.istodo;
      }
      setText() {
        this._node = document.createElement('div');
        this._node.appendChild(new Text(this.text));
        this._node.onclick = (event) => {
          alert(this.text)
        };
      }
      getNode() {
        return this._node;
      }
    }

    let container = document.getElementById('test');

    ['this is a todo component', 'this is a todo component #2', 'this is a todo component #3'].forEach(text => {
      let todo = new todos(text);
      todo.setText();
      container.appendChild(todo.getNode());
    });
<div id="test"></div>

Comments