uglycode
uglycode

Reputation: 3082

ES6, arrow function, context of "this"

I thought that arrow function is "just" a shortcut for antonymous functions, so I've been using it quite a lot. However, recently I came across an example that arrow function caused some issues. Here's a sample code:

function refreshTable() {
  $.ajax({
    url: root + `/posts?userId=${userId}`,
    method: 'GET'
  }).then(function(data) {

    for (var item of data) {
      $('table.list tbody').append(`
            <tr>
              <td>${item.id}</td>
              <td>${item.title}</td>
              <td>${item.date}</td>
              <td>
                <a href="" data-id="${item.id}" class="getDetails">View</a> | 
                <a href="" data-id="${item.id}" class="getDetails">Delete</a>
              </td>
            </tr>
          `);
    }

    $('.getDetails').click((e) => {
    // $(this) is actually the ajax call, I can't access the "data" part
    });

  });
}

However, this works:

    function refreshTable() {
  $.ajax({
    url: root + `/posts?userId=${userId}`,
    method: 'GET'
  }).then(function(data) {

    for (var item of data) {
      $('table.list tbody').append(`
            <tr>
              <td>${item.id}</td>
              <td>${item.title}</td>
              <td>${item.date}</td>
              <td>
                <a href="" data-id="${item.id}" class="getDetails">View</a> | 
                <a href="" data-id="${item.id}" class="getDetails">Delete</a>
              </td>
            </tr>
          `);
    }

    $('.getDetails').click(function(e) {
    // $(this) is the HTML element, so I can access "data"
    });

  });
}

Obviously, there is some logic to arrow functions, it creates a different scope for this. So, what's going on? Could I achieve the same thing with an arrow function (to access HTML) or is that not possible in this case?

Thanks!

Upvotes: 0

Views: 166

Answers (3)

Felix Kling
Felix Kling

Reputation: 816462

Could I achieve the same thing with an arrow function (to access HTML) or is that not possible in this case?

You can use an arrow function, but you can't use this. You can refer to the element the handler is bound to via the event object: e.currentTarget

This property will typically be equal to the this of the function.


So, what's going on?

See:

Upvotes: 1

Philippe Plantier
Philippe Plantier

Reputation: 8073

An arrow function does not create its own this context; rather, it captures the this value of the enclosing context.

In the specific case you are describing, you can just use $(e.target).data('id') to retrieve the data.

Upvotes: 0

Michelangelo
Michelangelo

Reputation: 5948

Well you are experiencing exactly what an arrow function does. It takes the this from the lexical or parent scope. http://exploringjs.com/es6/ch_arrow-functions.html

Second, their this is picked up from surroundings (lexical). Therefore, you don’t need bind() or that = this, anymore.

Yes, you can make it work, but you need to put the HTML Element outside of the click function. Then you can use this inside the function and not having the problem of using his own this.

Upvotes: 0

Related Questions