JavaScript JavaScript and the DOM Getting a Handle on the DOM Using CSS Queries to Select Page Elements

Error 'Uncaught TypeError: Cannot set property 'color' of undefined' for loop. What is the problem?

Hi, I got the error, could you help me understand why this appears? Here is my code:

const myHeading = document.getElementById('myHeading');
const myInput = document.getElementById('myInput');
const myButton = document.getElementById('myButton');
const myResetButton = document.getElementById('myResetButton');
const myCheckBox = document.getElementById('myCheckBox');
const myList = document.getElementsByTagName('li');

myButton.addEventListener( 'click', () => myHeading.style.color = myInput.value );

myResetButton.addEventListener('click', () => myHeading.style.color = 'black' );

myCheckBox.addEventListener( 'change', () => {
  myHeading.style.border = 'lightblue solid 2px';
  myHeading.style.borderRadius = '25px';
} );

for (let i in myList) { myList[i].style.color = 'purple'; } //ERROR FOR THIS STRING: 'Uncaught TypeError: Cannot set property 'color' of undefined'.

Meanwhile colours for the list change successfully but later code doesn't work.

Thank you!

1 Answer

Steven Parker
Steven Parker
203,238 Points

Generally for...in is not a good choice for iterating an array or collection.

In addition to the items with numbered indexes, in will also return items like "length". Trying to access the style property on such an item will return null.

Use a traditional for loop with a numeric index instead.

Thank you Steven! I read this from MDN:

'Although it may be tempting to use this as a way to iterate over Array elements, the for...in statement will return the name of your user-defined properties in addition to the numeric indexes. Thus it is better to use a traditional for loop with a numeric index when iterating over arrays, because the for...in statement iterates over user-defined properties in addition to the array elements, if you modify the Array object, such as adding custom properties or methods'

Now I understand that in general it's better not to use 'for in loop' for Arrays. BUT for the case I didin't add custom properties or methods. The code is very simple, so what is the problem? Btw Object also has 'length' property, but for objects 'for in' works fine. Really confused about this...

Steven Parker
Steven Parker
203,238 Points

Unlike a simple array, an HTMLCollection (as returned by getElementsByTagName) will have a "length" property, and "item" and "namedItem" methods by default. And these will be part of a for...in iteration even if you have not added any custom items.