Spot the bug - #96: Todo List Counter

DOM bug, pretty sneaky.

const items = document.querySelector('.todo li');
console.log(items.length);

Reply with what is broken and how you would fix it.

querySelector only returns a single item :slight_smile:

querySelector() returns one element, not a collection, so .length doesn’t exist.

Fix:


const items = document.querySelectorAll('.todo li');
console.log(items.length);

If you only need the first <li>, use querySelector() without .length.

Caught this exact thing during QA once, . length didn’t error out, it just came back undefined and the check silently passed like everything was fine. Kirupa’s site actually has a decent breakdown of querySelector vs querySelectorAll if anyone wants to go deeper on this.

you can’t use “.length” on variables only arrays?

1 Like

Length isn’t the issue. Strings have . length too, so does an array. It’s that querySelector hands you back a single DOM element object, and elements don’t have that property at all. I found a related Kirupa article that can help you go deeper into this topic:

. htm

@Sock - welcome to the forums! :slight_smile:

1 Like

welcome @Sock, glad to have you here! plenty of bugs to squash in this thread if you’re looking to warm up lol

1 Like

Spot the Bug answer: querySelector returns only a single element, not a list, so items.length is undefined instead of the count of matching li elements

The fix:

const items = document.querySelectorAll('.todo li');

Why:
querySelector returns the first matching element or null, which has no length property. querySelectorAll returns a NodeList of all matches, which does have a length property, so that is what should be used when you need a count.


Got it: @kirupa, @emmawalter5

First: @kirupa :trophy:

Close but not quite:

@Sock - Misdiagnoses the issue as a general rule about variables vs arrays instead of identifying that querySelector returns a single element/null lacking a length property.

2 Likes