0

I am trying to convert an HTML Collection of "li"s into an array, but the result in the array being emptied.

I read this question and applied that, but it doesn't work.How do I convert a HTMLCollection into an array, without emptying it?

<body>
  <ul id="base"></ul>
  <script>
   const json = [{
     "id" : "1", 
     "date" : "2013/05/05",
    },{
     "id" : "2", 
     "date" : "2019/05/05",
    }];

    for (item of json) {
      const list = document.createElement('li');
      list.textContent = `${item.date}`;
      base.appendChild(list)
    }
///the code above works fine.

    const base = document.getElementById("base");
    const myNodeList = base.getElementsByTagName("li");
    console.log(myNodeList);
    // gives HTMLCollection
    const myArray = Array.from(myNodeList)
    // returns empty array
  </script>
</body>

the result

enter image description here

I tested the same code on console and it worked fine as below.

```

Hammer
  • 25
  • 1
  • 5
  • If you just want to use array prototype methods, you can do the following: `Array.prototype.arrayMethod.call(htmlCollection, () => {});` arrayMethod can be any method you can call on arrays like fllter, forEach, map, etc.,. HTML collection is the NodeList returned by `document.getElementsByTagName`. It will be much better in terms of performance if you are handling a large number of nodes in a document. – Abrar Hossain Nov 18 '20 at 14:45

2 Answers2

1

The code cannot work before you are using base before initializing it. Placing the initialization before using it makes it work.

Here I modified it: https://jsfiddle.net/tk78z5gq/

Eriks Klotins
  • 4,042
  • 1
  • 12
  • 26
0

Thank you so much guys! The problem was async. I should have said that earlier, I fetch the data from NeDB with async function. The array was empty because DOM was executed before async function fetching data was executed. The full code below was fixed one. I'm not sure this is best way, but at least it worked.

    let dataM = null;

    async function getHTMLData() {
      const response = await fetch('/api');
      const data = await response.json();
      dataM = data;
      const base = document.getElementById("base");

      for (item of data) {
        const root = document.createElement('li');
        root.className = "col-md-auto";
        root.title = `${item.date}`;
        const border = document.createElement('div');
        border.className = "row no-gutters border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative";
        root.appendChild(border);
        const flex = document.createElement('div');
        flex.className = "col p-4 d-flex flex-column position-static";
        border.appendChild(flex);
        const country = document.createElement('strong');
        country.className = "d-inline-block mb-2 text-primary";
        const title = document.createElement('h3');
        title.className = "mb-0";
        const date = document.createElement('div');
        date.className = "mb-1 text-muted";
        date.id = "date";
        const fieldItem = document.createElement('p');
        fieldItem.className = "mb-auto";
        const imageRoot = document.createElement('figure');
        imageRoot.className = "image mb-2";
        const link = document.createElement('a');
        link.className = "p-4";
        const linkText = document.createTextNode("Source");

        country.textContent = `${item.country}`;
        title.textContent = `${item.title}`;
        date.textContent = `${item.date}`;
        fieldItem.textContent = `${(item.fieldItem)}`;

        for (var i = 0; i < item.imageSrc.length; i++) {
          const image = document.createElement('img');

          image.src = item.imageSrc[i];
          image.alt = 'seized items'
          image.className = "w-5 h-5";
          // image.crossOrigin ="use-credentials";
          imageRoot.appendChild(image);
        }
        const imageText = document.createElement('text');
        imageText.innerHTML = `<br>${item.imageText}`;
        imageRoot.appendChild(imageText);
        link.appendChild(linkText);
        link.title = "Source";
        link.href = item.URL;
        link.className = "";

        flex.append(country, title, date, fieldItem, imageRoot, link);
        base.appendChild(root);
      }
    }

    sortDate();
    async function sortDate() {
      const gethtml = await getHTMLData();
      const base = await document.getElementById("base");
      const myNodeList = await base.getElementsByTagName("li");
      const myArray = Array.from(myNodeList);
      myArray.sort(function (a, b) {
        return new Date(a.title) > new Date(b.title)? -1
             : new Date(a.title) < new Date(b.title)? 1
             : 0;
        })
      for (i = 0; i < myArray.length; i++) {
        base.appendChild(base.removeChild(myArray[i]))}
    } 

index.js

app.get('/api', (request, response) => {
  database.find({}).exec(function(err, data){
    if (err) {
      response.end();
      return;
    }
    response.json(data);
  })
});
Hammer
  • 25
  • 1
  • 5