1

Apologies in advance I feel as if this is a very simple solution and I am in the middle of a severe brain fart. I am simply trying to grab the data-id of an item I am clicking using ES6 syntax but no matter which way I run it I keep getting undefined.

HTML

<ul>
    <li class="list-item" data-id="item-1">Click me</li>
    <li class="list-item" data-id="item-2">Click me</li>
    <li class="list-item" data-id="item-3">Click me</li>
</ul>

JS

let $el = $('ul');

class List {
    constructor($el) {
        this.$el = $el;

        this.$listItem = $el.find('li');

        this.attachHandlers();
    }

    attachHandlers() {
        this.$listItem.on('click', () => {
            var data = $(this).attr('data-id');
            console.log(data);
        });
    }
}

const _init = () => {
    if ($el.length) {
        $el.each((i, v) => {
            new List($(v));
        });
    }
};

_init();

Ive simplified the code down as much as possible, anybody see what I am doing wrong here?

user934902
  • 1,184
  • 3
  • 15
  • 33

3 Answers3

1

The problem is in your attachHandlers method. Since you are using an arrow function, this refers to the class and not the element that was clicked.

Change the arrow function to a regular function.

JJJ
  • 3,314
  • 4
  • 29
  • 43
1

In addition to Josan's answer, if you want to continue using the arrow function, use it like this:

class List {
    constructor($el) {
        this.$el = $el;
        this.attachHandlers();
    }

    attachHandlers() {
        this.$el.on('click', 'li', (e) => {
            var data = $(e.currentTarget).attr('data-id');
            console.log(data);
        });
    }
}

For more discussion, refer to this thread.

31piy
  • 23,323
  • 6
  • 47
  • 67
  • this seems to return the data-id content of the first element in the list, not of the element that has been clicked. If I pass the event through and console.log e.currentTarget I can see the correct element but it always returns the data-id of the first element – user934902 Nov 27 '17 at 05:06
  • @user934902 -- Yes, because your constructor always sets the first `li` as `this.$listItem`. – 31piy Nov 27 '17 at 05:08
  • then I am confused about your answer on how using the arrow function as you have described will solve my issue – user934902 Nov 27 '17 at 05:18
  • @user934902 -- Please see my updated answer. That should solve the issue. You don't need to use `$listItem`. – 31piy Nov 27 '17 at 05:22
-2

Simpler and easier by just using JQuery:

$(".list-item").on('click', function() {
  console.log($(this).data('id'));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li class="list-item" data-id="item-1">Click me</li>
  <li class="list-item" data-id="item-2">Click me</li>
  <li class="list-item" data-id="item-3">Click me</li>
</ul>
Milan Chheda
  • 8,159
  • 3
  • 20
  • 35