title: Expand an iterable element or non-iterable element into an array without checking element .length
body: <p>Given <code>html</code></p>
  
  <pre><code>&lt;div&gt;&lt;/div&gt;
  &lt;div&gt;&lt;/div&gt;
  </code></pre>
  
  <p>calling <code>document.querySelector("div")</code> returns the first <code>div</code> element, where <code>.length</code> is not a property of the return value.</p>
  
  <p>Calling <code>document.querySelectorAll()</code> returns a <code>NodeList</code> having a <code>.length</code> property.</p>
  
  <p>The difference between the two return values of <code>.querySelector()</code> and <code>.querySelectorAll()</code> is that the former is not an iterable; and error will be thrown when attempting to use the <code>spread element</code> to expand the element into an array.</p>
  
  <p>In the following examples consider that either <code>div</code> or <code>divs</code> is a parameter received within the body of a functions call. Thus, as far as can gather, it is not possible to determine if the variable was defined as a result of <code>Element.querySelector()</code>, <code>Element.querySelectorAll()</code>, <code>document.querySelector()</code> or <code>document.querySelectorAll()</code>; further the difference between <code>.querySelector()</code> and <code>.querySelectorAll()</code> can only be checked using <code>.length</code>.</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>var div = document.querySelector("div");
  for (let el of div) {
    console.log(".querySelector():", el)
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div&gt;&lt;/div&gt;
  &lt;div&gt;&lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>logs</p>
  
  <pre><code>Uncaught TypeError: div[Symbol.iterator] is not a function
  </code></pre>
  
  <p>while </p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>var div = document.querySelectorAll("div");
  for (let el of div) {
    console.log(".querySelectorAll():", el)
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div&gt;&lt;/div&gt;
  &lt;div&gt;&lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>returns expected result; that is, <code>document.querySelectorAll("div")</code> is expanded to fill the iterable array.</p>
  
  <p>We can get the expected result at <code>.querySelector()</code> by setting <code>div</code> as an element of an <code>Array</code></p>
  
  <pre><code>[div]
  </code></pre>
  
  <p>at <code>for..of</code> <code>iterable</code> parameter.</p>
  
  <p>The closest have come to using same pattern for both or either <code>.querySelector()</code> or <code>.querySelectorAll()</code> is using <code>callback</code> of <code>Array.from()</code> and the <code>.tagName</code> of the variable, and <code>spread element</code>.
  Though this omits additional selectors that may have been called with <code>.querySelector()</code>, for example <code>.querySelector("div.abc")</code>. </p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>var div = document.querySelector("div");
  var divs = document.querySelectorAll("div");
  var elems = Array.from({length:div.length || 1}, function(_, i) {
    return [...div.parentElement.querySelectorAll(
      (div.tagName || div[0].tagName))
           ][i]
  });
  
  for (let el of elems) {
    console.log(".querySelector():", el)
  }
  
  elems = Array.from({length:divs.length || 1}, function(_, i) {
    return [...divs[0].parentElement.querySelectorAll(
      (divs.tagName || divs[0].tagName))
           ][i]
  });
  
  for (let el of elems) {
    console.log("querySelectorAll:", el)
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div&gt;&lt;/div&gt;
  &lt;div&gt;&lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>This does not provide adequate accuracy for additional reasons;  <code>Element.querySelector()</code> could have been originally passed to function, instead of <code>document.querySelector()</code>, similarly for <code>.querySelectorAll().
  Not sure if it is possible to retrieve the exact selector passed to</code>.querySelector, All` without modifying the native function?</p>
  
  <p>The desired pattern would accept the variable, and expand the contents of the iterable into an array if an <code>.querySelectorAll()</code> was used; which would treat <code>.getElementsByTagName()</code>, <code>.getElementsByClassName()</code>, <code>.getElementsByTagName()</code>, <code>.getElementsByName()</code> the same; or set the single value returned by <code>.querySelector()</code> as element of the array. </p>
  
  <p>Note, the current working solution is </p>
  
  <pre><code>div.length ? div : [div]
  </code></pre>
  
  <p>which iterates <code>div</code> if <code>div</code> has a <code>.length</code> property, possibly an iterable, though simply have a <code>.length</code> property and not be an <code>iterable</code>; else set <code>div</code> as single element of an array, an iterable.</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>var div = document.querySelector("div");
  var divs = document.querySelectorAll("div");
  var elems = div.length ? div : [div];
  
  for (let el of elems) {
    console.log(".querySelector():", el)
  }
  
  var elems = divs.length ? divs : [divs];
  
  for (let el of elems) {
    console.log("querySelectorAll:", el)
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div&gt;&lt;/div&gt;
  &lt;div&gt;&lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>Can this be achieved </p>
  
  <ul>
  <li>without checking the <code>.length</code> of the variable? </li>
  <li>without referencing the element three times on same line? </li>
  </ul>
  
  <p>Can the approach of the working solution </p>
  
  <ul>
  <li>be improved; that is should <code>[Symbol.iterator]</code> of <code>div</code> be checked instead of <code>.length</code>?</li>
  <li>is there magic using <code>.spread element</code> or <code>rest element</code> which could allow omission of checking <code>.length</code> of object?</li>
  <li>would using a <code>Generator</code>, <code>Array.prototype.reduce()</code> or other approach change the need to check the <code>.length</code> or <code>[Symbol.iterator]</code> property of a variable before expanding the element into an array?</li>
  </ul>
  
  <p>Or, is the above the approach the briefest possible given the difference between objects which are <code>iterable</code> or not <code>iterable</code>?</p>