Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Iterating: each and map

Most jQuery methods apply to all elements on their own. But sometimes each element needs its own treatment: read its data, count, compare. That is what each() is for.

The each method

<ul id="tasks">
  <li>Buy bread</li>
  <li class="done">Call Oleg</li>
  <li>Write the report</li>
</ul>
 
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
  $('#tasks li').each(function (index, element) {
    const $item = $(element);
    const mark = $item.hasClass('done') ? '[x]' : '[ ]';
 
    console.log(mark, $item.text());
  });
</script>

The function is called for every item. It receives the index and a plain DOM element, so the element is wrapped in $ to use jQuery methods. The output has three lines with marks.

this inside each

In a function declared with function, this points to the current element. Older code is written exactly like this:

<ul>
  <li>Buy bread</li>
  <li>Call Oleg</li>
</ul>
 
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
  $('li').each(function () {
    console.log($(this).text().length);
  });
</script>

An arrow function has no this of its own, so with it use the second argument, element.

Stopping early

To stop the loop, the function returns false:

<ul>
  <li>Buy bread</li>
  <li class="done">Call Oleg</li>
  <li class="done">Write the report</li>
</ul>
 
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
  $('li').each(function (index) {
    if ($(this).hasClass('done')) {
      console.log('First finished task is number', index + 1); // 2
      return false;
    }
  });
</script>

The loop stopped at the second item; the third was not checked.

The map method

map() builds new values from a set. The result is a jQuery object, and get() turns it into a plain array:

<ul>
  <li>Buy bread</li>
  <li>Call Oleg</li>
</ul>
 
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
  const titles = $('li').map(function () {
    return $(this).text();
  }).get();
 
  console.log(titles.join(', ')); // Buy bread, Call Oleg
</script>

The $.each and $.map functions

jQuery also has functions with the same names for plain arrays and objects. Their argument order differs:

CallCallback arguments
$('li').each(fn)index, element
$('li').map(fn)index, element
$.each(array, fn)index, value
$.map(array, fn)value, index

More on $.each in the lesson on utility functions. For arrays, the built-in forEach() and map() are more convenient today.

The same in plain JavaScript

<ul>
  <li>Buy bread</li>
  <li>Call Oleg</li>
</ul>
 
<script>
  const titles = Array.from(document.querySelectorAll('li'), (li) => li.textContent);
  console.log(titles.join(', '));
</script>

Common mistake

Forgetting get() after map(). Without it you get a jQuery object, not an array, and titles.join throws titles.join is not a function.

Thanks for reading!

Donate to the site — we work hard for you.