7

I'm completely stumped on this. I have three elements on the page with a class of .topic-link.

<div id="parent1">
  <a href="#" class="topic-link"></a>
</div>
<div id="parent2">
  <a href="#" class="topic-link"></a>
</div>
<div id="parent3">
  <a href="#" class="topic-link"></a>
</div>

I can run $('.topic-link').eq(0).parent(); in the JS console and get the correct parent returned. But when I iterate over them I get an empty object each time.

$('.topic-link').each( () => {
  console.log($(this).parent());
});

// returns 3 empty objects 
Andrew Jensen
  • 167
  • 1
  • 2
  • 14
  • Maybe if people commenting that this can't be reproduced actually tried to reproduce it you wouldn't be posting – Tibrogargan Oct 07 '16 at 18:44
  • @KevinB The better answer is [$('elems').each() with fat arrow](http://stackoverflow.com/questions/36548683/elems-each-with-fat-arrow) – Mohammad Oct 07 '16 at 19:08

2 Answers2

15

Arrow functions don't have their own this so what you have is not equivalent to

$('.topic-link').each(function () {
  console.log($(this).parent());
});

In your case this is window (or document or whatever depending on scope it is called in) which has no parent dom node

charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • 4
    Not sure why the downvote, this is correct. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions _"An arrow function does not create its own `this` context, so `this` has the original meaning from the enclosing context."_ – Jason P Oct 07 '16 at 18:50
  • :facepalm: Thanks a bunch! I totally forgot that about arrow functions. – Andrew Jensen Oct 07 '16 at 18:54
  • Apparently you can use arrow function syntax; you just need to pass in the arguments that `.each()` provides – j08691 Oct 07 '16 at 18:55
  • @j08691 sure...but that doesn't make anything here incorect, nor does it say this is what you need to do – charlietfl Oct 07 '16 at 18:55
  • I didn't say you were incorrect. And I upvoted you. I think the best answer for this question would combine your answer and Tibrogargan's – j08691 Oct 07 '16 at 18:56
  • @charlietfl My mistake. When I reproduced this I originally replaced the arrow function with a function as you did, but introduced my own issue with a typo. Both work. – Tibrogargan Oct 07 '16 at 18:59
  • @Tibrogargan i was really focusing on the *"why"* only anyway – charlietfl Oct 07 '16 at 19:00
  • @j08691 there's not enough code to combine them. I think charlietfl's answer is more concise - doesn't have the unused argument. – Tibrogargan Oct 07 '16 at 19:01
  • @Tibrogargan - The point is that arrow function syntax doesn't have a `this` of its own (charlietfl's point), however in this example if you pass it the arguments from `.each()` it will work (your point). I don't know what you mean that there's not enough code. – j08691 Oct 07 '16 at 19:03
  • @j08691 you could change this to a "normal" (i.e. not arrow style) function that took arguments, and use either `this` or the second argument, but why? You don't get any added value – Tibrogargan Oct 07 '16 at 19:04
  • Guys, it's cool. I got the answer I needed. Carry on. – Andrew Jensen Oct 07 '16 at 19:10
  • Not what I was looking for, but damn that's a cruel problem :p – Nick Bull Aug 29 '18 at 07:24
4

From @charlietfl's answer: You're getting this behavior because arrow functions don't bind their own this.

To continue using an arrow function the workaround would be to use the 2nd argument from .each(), the value of the object/array.

Example (arguments are required since the arguments variable is also not bound):

$('.topic-link').each( (∅, value) => {
  console.log($(value).parent());
});
Tibrogargan
  • 4,508
  • 3
  • 19
  • 38