Invite-Only Early Access — Think Throo GitHub App is currently invite-only. Request access here.
2024March

Lessons from open-source: Convert an array-like HTML NodeList to a standard javascript array.

This lesson is picked from next.js/packages/next. In this article, you will learn how to convert an array-like HTML Nodelist into a standard javascript array.

looseToArray Function:

The following code snippet is from https://github.com/vercel/next.js/blob/canary/packages/next/src/client/index.tsx#L78C1-L79C1

const looseToArray = <T extends {}>(input: any): T[] => [].slice.call(input)
  • looseToArray is a generic function that takes an input of type any.

  • It’s using the slice method on an empty array ([]) and calling it with input as its context ([].slice.call(input)).

  • The purpose is to convert something array-like (such as a NodeList) into a real array.

Notice the “any” type for input parameter. There are quite some places where “any” type is used in nextjs source code. I used to think “any” should be avoided at all costs, but it’s okay no code is too perfect.

const currentStyleTags: HTMLStyleElement[] = looseToArray<HTMLStyleElement>(
 document.querySelectorAll('style[data-n-href]')
)

The above snippet is picked from onStart function inside next/client.

  • document.querySelectorAll(‘style[data-n-href]’) selects all <style> elements with a data-n-href attribute in the document.

  • The result of this query is a NodeList, which is array-like but not a real array.

  • looseToArray<HTMLStyleElement> is used to convert the NodeList into a real array of HTMLStyleElement.

So, the looseToArray function is used here to convert the NodeList obtained from document.querySelectorAll into a standard JavaScript array. The purpose of using slice.call is a common technique to convert array-like objects into arrays because the slice method can be called on array-like objects, and it returns a new array.

If you are looking to practice next.js, checkout my website: https://tthroo.com/

Experiment

You can execute the following code to find out how HTML NodeList looks like after converting it to an array.

const looseToArray = function(input) {
  return [].slice.call(input);
};
 
const currentStyleTags = looseToArray(
  document.querySelectorAll('.pw-post-body-paragraph')
);
 
console.log("document.querySelectorAll('.pw-post-body-paragraph')", 
  document.querySelectorAll('.pw-post-body-paragraph'))
 
console.log("currentStyleTags", currentStyleTags);

You need to change document.querySelectorAll(‘style[data-n-href]’) to the relevant DOM selector function that finds an element in the browser.

Array-like NodeList

NodeList converted to array

Conclusion:

In JavaScript, the NodeList returned by document.querySelectorAll is not a true array but rather a collection of nodes. While it looks like an array, it lacks many of the array methods and properties. The looseToArray function in [nextjs source code]

About me:

Hey, my name is Ramu Narasinga. Email: ramu.narasinga@gmail.com

Tired of AI-generated code that works but nobody understands?

I spent 3+ years studying OSS codebases and wrote 350+ articles on what makes them production-grade. I built an open source tool that reviews your PR against your existing codebase patterns.

Your codebase. Your patterns. Enforced.

Get started for free —thinkthroo.com