1

I am trying to make a class that creates a list element while attaching an event listener to it. The following is my code:

class listItem {

    constructor(id) {
        this.id = id;       
        this.li = $("<li>");
        this.li.text(this.id);

        // Selector
        this.li.on("click", function() {
            this.li.text("clicked");
        });
    }

    getDom() {
        return this.li;
    }
}

I invoke this class using the following:

// Creating a new listElement and appending it to the list
var l1 = new listItem(1);
$("ul").append(l1.getDom());

However, when I click on the element, I get the following error message:

Uncaught TypeError: Cannot read property 'text' of undefined

at HTMLLIElement. ((index):56)

at HTMLLIElement.dispatch (jquery.js:5206)

at HTMLLIElement.elemData.handle (jquery.js:5014)

Here is my jsfiddle of the code.

1 Answer 1

3

The problem is the this's context. You're using the this's context of this.li.on("click", function() {...} rather than of your class listItem.

Store the this value into a variable, i.e: $self.

let $self = this;

class listItem {

    constructor(id) {
        this.id = id;       
        this.li = $("<li>");
        this.li.text(this.id);
        
        let $self = this;
        
        this.li.on("click", function() {
            $self.li.text("clicked");
        });
    }

    getDom() {
        return this.li;
    }
}


var l1 = new listItem(1);
$("ul").append(l1.getDom());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
</ul>

See? now the li element is changing.

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

3 Comments

That does help! Quick question, is there a particular reason you use 'let'? I'm a bit unfamiliar with the term.
let it's a keyword for scoping of your variables, you can use var because the scope of your variable is local. Read that link to learn a little more.
In jQuery, I thought it should be $("li") instead of $("<li>")?

Your Answer

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