0

I'm looping through divs to find the single 'active' class on a series of divs. I then want to get the data attribute from that div. I'm getting the data attribute fine but can't seem to pass it out of the function with a return. It logs undefined.

const getPostcardLink = () => {
  console.log('getPostcardLink()...');
  $('.postcard').each(function () {
    if ($(this).hasClass('active')) {
      const postcard = $(this).data('postcard');
      console.log(postcard);
      return postcard;
    }
    return 'error';
  });
};

const getStampLink = () => {
  console.log('getStampLink()...');
  $('.stamp').each(function () {
    if ($(this).hasClass('active')) {
      const stamp = $(this).data('stamp');
      console.log(stamp);
      return stamp;
    }
    return 'error';
  });
};

function updatePostcard() {
  const postcard = `images/_${getPostcardLink()}.jpg`;
  const stamp = `images/_${getStampLink()}.jpg`;
  console.log(`${postcard} with ${stamp}`);
}

$(document).ready(() => {
  updatePostcard();
});

Log returns...

getPostcardLink()...
p1
getStampLink()...
s1
images/_undefined.jpg with images/_undefined.jpg
gyre
  • 16,369
  • 3
  • 37
  • 47
Layne
  • 642
  • 1
  • 13
  • 32
  • 3
    `getStampLink` does not return anything - there simply is no `return` statement there. – zerkms Mar 06 '17 at 20:28
  • 3
    `return stamp;` returns from the `.each` callback, not from `getStampLink`. Similar for the other function. `return` does not cross function boundaries, it only returns from the function it is contained in. – Felix Kling Mar 06 '17 at 20:28
  • How do you handle case of `"error"` being returned? Substitute using `.filter()` for `.each()`, check if return value of `.filter()` has `.length` greater than `0` – guest271314 Mar 06 '17 at 20:35
  • @Felix Kling: That helps me fix my code. Many thanks! – Layne Mar 06 '17 at 20:48
  • I'm going to explore @guest271314's filter suggestion also. – Layne Mar 06 '17 at 20:48
  • @MikeMcCaughan fwiw, would not consider present Question a duplicate of linked Question, but inappropriate jQuery method selection and usage given expected result. Although `.each()` can be used, `.filter()` is available for the specific case of `javascript` at Question. – guest271314 Mar 06 '17 at 20:51
  • @guest271314 The question was asking why the function was not returning the data returned from `.each()`. The linked question's answers details exactly why. Not sure how that's not a duplicate. If you wanted to answer *that* question with the use of `.filter()`, I'm sure it would be well received (maybe not with the accept checkmark, but at your rep, you don't really need more of those, right?) – Heretic Monkey Mar 06 '17 at 21:12
  • @MikeMcCaughan _"The question was asking why the function was not returning the data returned from `.each()`."_ Because `.each()` was inappropriate jQuery method to use to filter elements. There are other options designed for that case. OP is trying to solve a problem. The problem can solved by not using `.each()`. How is using `.each()` more appropriate than using `.filter()` given the `javascript` at Question? Though, OP now should be aware how to use either approach to get expected result. – guest271314 Mar 06 '17 at 21:15

1 Answers1

1

Use .filter() and same pattern at getStamp()

const getPostcardLink = () => {
  console.log('getPostcardLink()...');
  let elems = $('.postcard').filter(function () {
    return $(this).hasClass('active')
  });
  if (elems.length) {
      const postcard = elems.data('postcard');
      console.log(postcard);
      return postcard
  }
  return "error"
};

function updatePostcard() {
  let cLink = getPostcardLink();
  let sLink = getStampLink();
  if (cLink !== "error") const postcard = `images/_${cLink}.jpg`;
  if (sLink !== "error") const stamp = `images/_${sLink}.jpg`;
  if (postcard && stamp) console.log(`${postcard} with ${stamp}`);
}
guest271314
  • 1
  • 15
  • 104
  • 177
  • 1
    You could also pass a selector to `filter`, like `$('.postcard').filter('.active')` – gyre Mar 06 '17 at 20:44