1

I know I can do this with a simple for loop but I'm trying to understand better how to use forEach.

What I'm trying to do is, having a list of "a" elements coming from a querySelectorAll(), to obtain an array with the href attributes. What is wrong?

var links = document.querySelectorAll("a");
function get_hrefs(links){
    var links_array = links.forEach(function(elem){ return elem.getAttribute("href"); });
    return links_array;
}
get_hrefs(links);
2
  • 3
    document.querySelectorAll("a") return a NodeList and not an array Commented Jul 29, 2015 at 10:05
  • The error in the web console should be giving you some idea what the first problem is. Any documentation on forEach should be giving you an idea what the second problem is. Commented Jul 29, 2015 at 10:06

5 Answers 5

8

Use slice to get an Array, like this:

var links = Array.prototype.slice.call(document.querySelectorAll("a"));
var links_array = links.map(function(elem){ return elem.getAttribute("href"); });

As for the updated question:

var links = document.querySelectorAll("a");

function get_hrefs(links){
    links = Array.prototype.slice.call(links);

    return links.map(function(elem){ return elem.getAttribute("href"); });;
}

get_hrefs(links);
Sign up to request clarification or add additional context in comments.

6 Comments

love the answer but, what if the links are given outside the function?
Such a shame 4 other > 6k users didn't test their code. +1 for being the only one that provides a working answer.
I updated the example on my answer to be a little more specific about the date I must use, could you check it?
@Vandervals: Doesn't make any difference.
Just one more thing... in your opinion, support for map is good enough??
|
2

You're looking for map rather than forEach, and you need to call it differently because querySelectorAll returns a NodeList, not an arary:

var links = document.querySelectorAll("a");
var links_array = Array.prototype.map.call(links, function(e){
    return e.getAttribute("href");
});

That's if you really want the attribute value. If you want the resolved href, then:

var links = document.querySelectorAll("a");
var links_array = Array.prototype.map.call(links, function(e){
    return e.href;
});

Re your updated question, where the function will receive links and not necessarily know what it is: The code above will work both for true arrays and for array-like things like the NodeList returned by querySelectorAll. So no changes needed to handle it.

Comments

1

Just came to this question late — but I believe that this can be achieved in one concise line of code by combining Array.from and the map() function:

Array.from(document.querySelectorAll('a')).map(e=>e.href)

Comments

0

If you want to use foreach, because querySelectorAll doesn't return array so you can do something like this:

var links = document.querySelectorAll("a");
var links_array = [];
[].forEach.call(
  links, 
  function(elem){
    links_array.push(elem.getAttribute("href"));
  }
);

Comments

-1
var hrefArray = [];
var links = document.querySelectorAll("a");
var Array.prototype.forEach.call(links, function(elem){ hrefArray.push(elem.getAttribute("href")); });

Let forEach push the elements into an empty array. forEach just iterates over all the elements. What you do with it is your decision.

Other users are pointing to the use of map. That functions suits the problem well. However the question was to get a better understanding of forEach.

Cerbrus pointed us to the fact that querySelectorAll returns a nodelist. Which I overlook at first. instead of an array. Now a nodelist is arrayish. So you can still treat it as one by using Array.prototype.forEach.call();

Since nodelist doesn't have the function forEach we need to invoke it from the Array object. Then we pass a reference to links using the first argument of call.

1 Comment

querySelectorAll doesn't return an array.

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.