I am trying to use map function in my code, but I am afraid that I am making some silly mistakes. It just does not work!
Here is my code. I have 2 buttons captioned "ID" and "Text". Clicking them should show the list of IDs and texts of the input field. The program works fine until the map
.
Can you Gurus help me understand my mistake?
<!DOCTYPE html>
<html>
<head>
<script>
getID = (x) => x.id;
getText = (x) => x.value;
function Click(x) {
input = document.getElementsByTagName("input");
alert(input.map((x.id == "id") ? getID : getText));
}
</script>
</head>
<body>
<input type="input" id="input1"> </input>
<input type="input" id="input2"> </input>
<button id="id" onclick="Click(this)"> ID </button>
<button id="text" onclick="Click(this)"> Text </button>
</body>
</html>
2
Answers
The
.map()
method is part of theArray.prototype
which allows you to use it on arrays, however,input
in your case is not an array, it’s a HTMLCollection (as that’s whatgetElementsByTagName
returns). You could convert theHTMLCollection
to an array using the spread syntaxconst inputArray = [...input];
, or usingconst inputArray = Array.from(input)
and once converted perform your mapping with.map()
, however, it would be more efficient to use the second argument ofArray.from()
to perform your mapping while converting (this avoids two iterations over your collection):On a side note, you should declare
getID
andgetText
withconst
orlet
to scope them to your current script and to avoid making them global. The same idea applies toinput
, declare this withconst
/let
/var
to keep it scoped to your function where it’s declared:The issue in your code is with how you’re trying to use the map function. getElementsByTagName returns an HTMLCollection, which is an array-like object, not an actual array. Therefore, you can’t directly use array methods like map on it.
To fix this, you can convert the HTMLCollection into an array before using map. You can use Array.from or the spread operator … for this purpose.
Here’s the corrected code: