1

I am working on a javascript file and have code like following

class test(){
    constructor(){
    }
    showBox(){
        var countBlock = document.createElement("div");
        document.body.appendChild(countBlock); 
        countBlock.addEventListener('click', function(){
            this.showList()
        });
    }
    showList(){
        console.log('Element clicked')
    }
}

Code is working fine unless I click on element, when I click it shows this.showList() is not a function

Not sure how to resolve it

Mosè Raguzzini
  • 15,399
  • 1
  • 31
  • 43
Vikram
  • 3,171
  • 7
  • 37
  • 67

3 Answers3

8

Use an arrow function:

countBlock.addEventListener('click', () => this.showList());

Arrow functions lexically bind their context so this refers to the original context, which is the context of the code that contains the arrow function.

Or use a regular function but bind the enclosing this to your function:

countBlock.addEventListener('click', function () { this.showList() }.bind(this));
// or shorter, no need to wrap it in a function:
countBlock.addEventListener('click', this.showList.bind(this));

You can read more about this here.

Here is an example based on your code:

class Test {
  showBox() {
    const countBlock = document.createElement('p');
    document.body.appendChild(countBlock); 
    countBlock.addEventListener('click', () => this.showList());
  }
  showList() {
    console.log('Element clicked')
  }
}

new Test().showBox();
p {
  width: 20px;
  height: 20px;
  background: black;
  cursor: pointer;
}
jo_va
  • 13,504
  • 3
  • 23
  • 47
  • Thanks , That was a Quick and a perfect solution. Can you recommend me some articles or tutorials for javascript, I worked in jQuery and have only basic knowledge in javaScript – Vikram Apr 18 '19 at 11:34
  • @Vikram Singh, you are welcome, a great reference for JavaScript would be [You don't know JS](https://github.com/getify/You-Dont-Know-JS), I find it very useful, otherwise, the documentation on MDN is great too. – jo_va Apr 18 '19 at 11:35
1

class test(){ seems to be wrong, secondly use arrow function to bind this

class Test {
  constructor() {}
  showBox() {
    console.log('Show Box Executed')
    var countBlock = document.createElement("div");
    let txt = document.createTextNode('Div');
    countBlock.appendChild(txt);
    document.body.appendChild(countBlock);
    countBlock.addEventListener('click', () => {
      this.showList()
    });
  }
  showList() {
    console.log('Element clicked')
  }
}
let _t = new Test();
_t.showBox();
brk
  • 48,835
  • 10
  • 56
  • 78
0

this.showList is outside of the test class's scope because you wrapped it inside an anonymous function. Do it like this:

class test{
    constructor(){
    }
    showBox(){
        var countBlock = document.createElement("div");
        document.body.appendChild(countBlock); 
        countBlock.addEventListener('click', this.showList);
    }
    showList(){
        console.log('Element clicked')
    }
}
obscure
  • 11,916
  • 2
  • 17
  • 36