2

I'm trying to access the data-id of my div on click. The domain models are projects and todos for users. This is my current implementation (working):

  // script-tag bottom of user-page.html, before footer include (jinja2)
  const projects = '{{projects | count}}';
  for (let i = 1; i <= projects; i++) {
    const click_id = `#clickable-${i}`;

    $(click_id).on("click", () => {
        const data = $(click_id).data();
        redirectToProjectPage(data);
    });
  }

and html:

  {% for project in projects %}
    <div id="clickable-{{loop.index}}" data-id="{{project.id}}" style="display:inline-block;">
       ... stuff.
    </div>
  {% endfor %}

Now I've tried to implement the refactoring by using jQuery.each and jQuery.on by browsing SO and referencing jQuery documentation, but following code produces undefined for me. Note: in the html I swapped the id for a class of "clickable".

  $('.clickable').each(() => {
      const $this = $(this);
      $this.on('click', () => {
          const id = $(this).data('id')
          console.log(id) // produces undefined
          redirectToProjectPage(id)
      });
  });

How do I proceed?

Edwin Carlsson
  • 103
  • 1
  • 8

2 Answers2

3

You're running into the Javascript infamous Loop issue?.

Use $(this) in the click handler. For this to work you have to use a regular function, not an arrow function.

  const projects = '{{projects | count}}';
  for (let i = 1; i <= projects; i++) {
    const click_id = `#clickable-${i}`;

    $(click_id).on("click", function() {
        const data = $(this).data();
        redirectToProjectPage(data);
    });
  }

You're having the same problem in your .each() loop. It can't pass the current element in this to an arrow function.

Are 'Arrow Functions' and 'Functions' equivalent / exchangeable?

Barmar
  • 741,623
  • 53
  • 500
  • 612
1

$(this) wont work if you use arrow function if you need to use $(this), you should use function() {} closure else if you need to use arrow function, you have to pass an event parameter and can use the element by $(event.currentTarget)

$('element').click(function () { 
    const data = $(this).data('id'); 
});

else,

$('element').click((event) => { 
    const data = $(event.currentTarget).data('id');
});
S K R
  • 552
  • 1
  • 3
  • 16