Avoid Errors With document.querySelector and document.querySelectorAll

I almost exclusively use document.querySelector and document.querySelectorAll in my JavaScript. More recently I’ve been focusing on adding more safeguards to my code so it fails more gracefully.

I just recently learned there’s a difference between how they behave when they don’t find an element. Today I wanted to quickly discuss the difference between querySelector and querySelectorAll and how to handle errors.

Credit goes to Chris Ferdinandi, author of GoMakeThings. His articles have really helped me with JavaScript.

What’s the difference between querySelector and querySelectorAll? #

When querySelector doesn’t find a matching selector, the value of the variable will be null.

For example:

var missingElement = document.querySelector('.missing');

console.log(missingElement);
// null

Why does this matter? If we’re using document.querySelector in our functions we can quickly bail if an element isn’t found:

function findElement() {
    var missingElement = document.querySelector('.missing');
    console.log(missingElement); // null

    if (!missingElement) return 'Element not found';

    // Continue if element found...
}

querySelectorAll behaves differently. If it doesn’t find any elements it will still be defined as a NodeList. Which means if we check whether our element is truthy or falsy, it will return true.

var missingElements = document.querySelectorAll('.missing');

console.log(missingElements); // NodeList[]

if (missingElements) {
    // true because missingElements is a NodeList
    console.log('I will run');
}

Preventing Errors with document.querySelectorAll #

So how should we prevent errors with querySelectorAll? Previously I would use instanceof to check if my variable was a NodeList, but this doesn’t work because querySelectorAll always returns a NodeList.

var missingElements = document.querySelectorAll('.missing');

console.log(missingElements); // NodeList[]

if (missingElements instanceof NodeList) {
    // true because missingElements is a NodeList
    console.log('I will run');
} else {
    console.log('I will never run because missingElements is always a NodeList');
}

Instead we can use the length property on the NodeList.

When querySelectorAll finds nothing, the length will be 0. So we can use that to check whether querySelectorAll actually found some items or not.

var missingElements = document.querySelectorAll('.missing');

if (missingElements.length === 0) {
    console.log('no elements found');
} else {
    console.log('I found some elements');
}

You might also like