1

I want to save a set of ids based on a nodeList returned by a querySelector.

I achieved it with a very procedural approach, thinking in terms of steps.

  1. Select items
  2. Create an array
  3. Iterate over items
  4. Get the id
  5. Push it into the array

const getThem = document.querySelectorAll('.get-me');

let arrayOfData = [];

Array.prototype.forEach.call (getThem, function (node){
    arrayOfData.push(node.id);
});

console.log(arrayOfData);
<ul>
<li class="get-me" id="one">One</li>
<li class="get-me" id="two">Two</li>
<li class="get-me" id="three">Three</li>
</ul>

I wonder if I can get this done with array map, to reduce the amount of lines and also take advantage of modern Javascript features.

I tried with:

const getThem = document.querySelectorAll('.get-me');
Array.prototype.map.call(getThem, (item) => ({ [id]: item.id }));
console.log(getThem);

But it doesn't work.

1
  • 1
    NodeLists don't have a .map(..) function but you can convert it to an array pretty easily, something like [...getThem]. Here is a complete example: [...getThem].map((node) => node.id) Commented Dec 11, 2022 at 11:58

3 Answers 3

1

Unfortunately, the NodeList that is returned by .querySelectorAll() doesn't have a .map() method. However, as it is iterable, you can pass it to Array.from(), and use the second mapping argument to perform your mapping:

const getThem = document.querySelectorAll('.get-me');
const arrayOfData = Array.from(getThem, node => node.id);
console.log(arrayOfData);
<ul>
  <li class="get-me" id="one">One</li>
  <li class="get-me" id="two">Two</li>
  <li class="get-me" id="three">Three</li>
</ul>

This does two things in one go, it converts your NodeList to an array, and it performs the mapping based on the second argument. This is opposed to doing something like Array.from(getThem).map(...) and [...getThem].map(...) which both do two iterations over your items.


I tried with:

const getThem =
document.querySelectorAll('.get-me');
Array.prototype.map.call(getThem, (item) => ({ [id]: item.id }));
console.log(getThem); 

But it doesn't work.

This does also work, you just need to store the return value in a variable a log that. .map() doesn't change the original array, it returns a new one instead:

const getThem = document.querySelectorAll('.get-me');
const res = Array.prototype.map.call(getThem, (item) => item.id);
console.log(res);
<ul>
  <li class="get-me" id="one">One</li>
  <li class="get-me" id="two">Two</li>
  <li class="get-me" id="three">Three</li>
</ul>

Sign up to request clarification or add additional context in comments.

Comments

1

Another way to do it using spread operator and array map like below

const getThem = document.querySelectorAll('.get-me');
const nodes = [...getThem];

const arrayOfData = nodes.map(node => node.id);

console.log(arrayOfData);
<ul>
  <li class="get-me" id="one">One</li>
  <li class="get-me" id="two">Two</li>
  <li class="get-me" id="three">Three</li>
</ul>

1 Comment

Thanks a lot, really appreciate it. I'll accept the other answer because it was first. But the real accepted answer should be both combined. :-)
0

You can do:

const elems = document.querySelectorAll('.get-me')
const arrayOfData = Array.from(elems).map(({ id }) => id)

console.log(arrayOfData)
<ul>
  <li class="get-me" id="one">One</li>
  <li class="get-me" id="two">Two</li>
  <li class="get-me" id="three">Three</li>
</ul>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.