How to silently fail querySelector() like jQuery() if element does not exists

Viewed 1109

I can't get this thing right.
Why jQuery() outputs an object by default? And is there some way to achieve same result with JavaScript?

jQuery('#configurator-material')
init [section#configurator-material.section, context: document, selector: "#configurator-material"]

document.querySelector('#configurator-material');
<section id=​"configurator-material" class=​"section" ng-controller=​"materialCtrl as material">​…​</section>​

document.querySelectorAll('#configurator-material');
NodeList [section#configurator-material.section]

In general my problem is that at some point I have this line:

jQuery('#myid').addClass('myclass');

im trying to replace it with JS like this:

document.querySelector('#myid').classList.add('myclass');

I thought that it should be fine and without errors,
but i'm getting "Cannot read property 'classList' of null" on the JS variant if a specific element does not exists on the page.

1 Answers

Handling non existent Elements

Internally the jQuery library conditionally handles non existent elements - failing silently without error.
Take for example a $("#nonExistent"), even if the Element is not retrieved in the DOM, the returned value will still be a jQuery Object instance - with all its constructor methods available, like .addClass() etc.

In contrast, JavaScript's .querySelector() returns an Element Object, but if the element is not found — the primitive null is returned.
JavaScript will break your code if you try to access properties of non-Object. Just like manually writing null.classList will throw an error:

Uncaught TypeError: Cannot read properties of null

Use JavaScript Optional Chaining .?

The simplest way to emulate the similar non-erratic behavior is to use the Optional Chaining operator .?

// jQuery
$("#notExistent").addClass("red"); // No errors

// JavaScript
document.querySelector("#notExistent")?.classList.add("red"); // No errors
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

Use Babel if you need support for IE browser - or use an if statement:

// JavaScript
const EL_notExistent = document.querySelector("#notExistent");
if (EL_notExistent) EL_notExistent.classList.add("red"); // No errors

Related