Lessons from open-source: Convert an array-like HTML NodeList to a standard javascript array.
Tags: javascript, react, nextjs, node
Published: 2024-03-07 21:51:27

This lesson is picked from [next.js/packages/next](https://github.com/vercel/next.js/blob/canary/packages/next/src/client/index.tsx#L78C1-L79C1). 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.](https://github.com/vercel/next.js/blob/canary/packages/next/src/client/index.tsx#L676)

- `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

![Array-like NodeList](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rjj70sp6slsa49ahfh23.png)

### NodeList converted to array

![NodeList converted to array](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n290ixy13gvralsuzdin.png)

## 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](https://github.com/vercel/next.js/blob/canary/packages/next/src/client/index.tsx#L78) is used to convert the NodeList into a regular array.