0

I keep getting TypeError: Cannot read property 'forEach' of null in my Javascript because I'm not checking for null after a document.querySelectorAll() call.

Is there a way to create a special forEach() on the Javascript null object, and make it do nothing, thereby eliminating the error? Or, can we replace the forEach() that I use with .forEach2() so that forEach2() won't do anything on a null?

For example:

var $ = s => document.querySelectorAll.bind(document)(s).length > 1 ? document.querySelectorAll.bind(document)(s) : document.querySelector.bind(document)(s);

$('FOOTER EM').forEach(function(el,i){
  console.log(el);
});

The above is generating an error for me if there is no EM under FOOTER, such as at runtime I sometimes add some.

Volomike
  • 23,743
  • 21
  • 113
  • 209
  • [`.querySelectorAll()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll) will never return `null`. The only return value is a `NodeList` which can be empty. – Andreas Mar 31 '21 at 18:13
  • _"The Document method `querySelectorAll()` returns a static (not live) `NodeList` representing a list of the document's elements that match the specified group of selectors."_ - From the above linked documentation. – Andreas Mar 31 '21 at 18:14
  • @Andreas maybe it's how I'm really doing it. I'm doing: `var $ = s => document.querySelectorAll.bind(document)(s).length > 1 ? document.querySelectorAll.bind(document)(s) : document.querySelector.bind(document)(s); ` – Volomike Mar 31 '21 at 18:14
  • myArray||[].forEach(function (value) { console.log(value); }); – Bryan Dellinger Mar 31 '21 at 18:15
  • 1
    What is this `document.querySelectorAll.bind(document)` construct supposed to do/solve? o.O – Andreas Mar 31 '21 at 18:21
  • @Andreas it slightly simulates the old $ tool of jQuery, which I'm not using here. – Volomike Mar 31 '21 at 18:22
  • Why do you query the DOM always twice. One time with `.querySelectorAll()` and another one with either `.querySelectorAll()` or `.querySelector()`? o.O Do it once with `.querySelectorAll()` and return the result - which will also fix your problem. – Andreas Mar 31 '21 at 18:23
  • @Calculuswhiz https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach – Andreas Mar 31 '21 at 18:23
  • @Andreas Darn, right. Was testing on IE with a polyfill for Array.from. Sorry. – General Grievance Mar 31 '21 at 18:24
  • 1
    _"it slightly simulates the old $"_ - No, it just adds unnecessary steps... `document` won't ever change – Andreas Mar 31 '21 at 18:24
  • Good read NodeList vs. Array: https://gomakethings.com/converting-a-nodelist-to-an-array-with-vanilla-javascript/ – ikiK Mar 31 '21 at 18:29

1 Answers1

1

Is there a way to create a special forEach() on the Javascript null object, and make it do nothing

Not exactly a special function, you can use an optional chaining method call for this:

$('FOOTER EM')?.forEach(el => console.log(el));
//            ^

However, it would be a much better practice to simply not have your $ function return null instead of an empty array:

const $ = s => document.querySelectorAll(s);
// or
// const $ = document.querySelectorAll.bind(document);

for (const el of $('FOOTER EM')) console.log(el);
Bergi
  • 630,263
  • 148
  • 957
  • 1,375