0

I have a JS-class with some events

jQuery(document).on('click', '.btn-details', (e) => {

but I can't access the data-attr tthe .btn-details has.

when I do a

jQuery(document).on('click', '.btn-details', function() {

I can access the data-attr of the btn-details-element, but not the this.myvar-class-variable.

what is the problem here? what does this (e) => exactly mean?

bwegs
  • 3,711
  • 2
  • 27
  • 31
99Problems
  • 125
  • 2
  • 8
  • 1st answer is : http://stackoverflow.com/a/38582643/747579 – Abdennour TOUMI Jul 26 '16 at 06:44
  • Related: [What's the meaning of “=>” (an arrow formed from equals & greater than) in JavaScript?](http://stackoverflow.com/q/24900875/218196), [Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?](http://stackoverflow.com/q/34361379/218196) – Felix Kling Jul 26 '16 at 09:19

5 Answers5

2

They both are function calls. The difference is that in first call, you use an arrow function with the event parameter (e).

Arrow function

(param1, param2, …, paramN) => { statements }

As stated in the documentation

An arrow function does not create it's own this context, rather it captures the this value of the enclosing context

So, I assume you are trying to get the data attribute using the this keyword

$(this).attr('data-test')

but, in arrow function, the this refers to the object of the enclosing context, not to the specific object.


The second one is a classic function call and this refers to the clicked element, so here you can successfully get the 'data-test' attribute.


EXAMPLE

Check this live example

In both buttons, the this object is writen in the console.log. Using the normal function the console outputs teh clicked element (the button) but, using the arrow function the console outputs the window object.

kapantzak
  • 10,937
  • 4
  • 36
  • 54
2

Warning While they are both ways of defining a function, they are not the same. Read more details on MDN Documentation.

Arrow functions automatically bind this to the current context.
If you are using jQuery this is a problem if you are trying to use this to refer to the current target.

$('div').click(function() {
  console.log(this) // the click target as expected
})

$('div').click(() => {
  console.log(this) // not the click target because jQuery can't bind it
})

If you want to use an arrow function, you can accept the event as an argument to your callback:

$('div').click((e) => {
  console.log(e.currentTarget) // click target as expected
  console.log(this) // enclosing context - could be useful
}

This can actually be handy if you want to keep track of the enclosing context from within the callback.

Damon
  • 3,566
  • 2
  • 14
  • 26
1

Using an arrow ()=> function binds the "this" keyword from the original caller's "this" to the one inside the function scope.

Giovanni Lobitos
  • 832
  • 7
  • 19
1

The safest way to access the related elements (I mean without messing with this context) is to use the appropriate event properties.

  • e.target refers to the actual event target
  • e.currentTarget refers to the delegated event target (same as this)

So in your case you can always access the .btn-details element with e.currentTarget.

Zoltán Tamási
  • 10,479
  • 3
  • 51
  • 73
1

e contains the click event properties. it's commonly used with an global-like (document scoped) event like this:

jQuery(document).on('click', '.btn-details', (e) => {
   var btnDetails = e.target;
   var attr = btnDetails.data("attr");
}

or

jQuery(document).on('click', '.btn-details', function(e) {
   var btnDetails = e.target;
   var attr = btnDetails.data("attr");
}

the original event receiver is the document element, because you had bound the listener method to it, but you can get the triggering element by querying e.target inside it.

Taha Paksu
  • 14,293
  • 1
  • 39
  • 67