json - Iterate through Multidimensional array in plain Javascript - Stack Overflow

I have the following Json file and I am trying to iterate through everything however only 1 item from t

I have the following Json file and I am trying to iterate through everything however only 1 item from the nested array is showing up. Not sure what I am doing wrong here.

JSON:

{
   "items":[
      {
         "label":"red",
         "url":"red",
         "items":[

         ]
      },
      {
         "label":"blue",
         "url":"#/blue",
         "items":[
            {
               "label":"green",
               "url":"#/green"
            },
            {
               "label":"yellow",
               "url":"#/yellow"
            },
            {
               "label":"pink",
               "url":"#/pink"
            }
         ]
      },......

JS:

var d = document, 
        main = d.getElementsByTagName('nav')[ 0 ],
        ul = d.createElement( 'ul' ),
        i;

        main.appendChild( ul );

        axios.get('../data/colors.json')
        .then(function (response) {
            console.log(response.data.items);

            for( var i in response.data.items ){
                var li = d.createElement( 'li' ); 
                if(response.data.items[i].items.length){
                    li.innerHTML = "<a class='meta'>" + response.data.items[i].label + "<div>" + response.data.items[i].items[i].label + "</div>" + "</a>"; // create a new li element
                }
                else {
                    li.innerHTML = "<a class='meta'>" + response.data.items[i].label + "</a>"; // create a new li element
                }
                ul.appendChild( li );// every time append a new item

            }

        })
        .catch(function (error) {
            console.log(error);
        });

Desired output:

<ul>
<li>red<li>
<li>blue
  <div>green </div>
  <div>yellow </div>
  <div>pink</div>
</li>
</ul>

I have the following Json file and I am trying to iterate through everything however only 1 item from the nested array is showing up. Not sure what I am doing wrong here.

JSON:

{
   "items":[
      {
         "label":"red",
         "url":"red",
         "items":[

         ]
      },
      {
         "label":"blue",
         "url":"#/blue",
         "items":[
            {
               "label":"green",
               "url":"#/green"
            },
            {
               "label":"yellow",
               "url":"#/yellow"
            },
            {
               "label":"pink",
               "url":"#/pink"
            }
         ]
      },......

JS:

var d = document, 
        main = d.getElementsByTagName('nav')[ 0 ],
        ul = d.createElement( 'ul' ),
        i;

        main.appendChild( ul );

        axios.get('../data/colors.json')
        .then(function (response) {
            console.log(response.data.items);

            for( var i in response.data.items ){
                var li = d.createElement( 'li' ); 
                if(response.data.items[i].items.length){
                    li.innerHTML = "<a class='meta'>" + response.data.items[i].label + "<div>" + response.data.items[i].items[i].label + "</div>" + "</a>"; // create a new li element
                }
                else {
                    li.innerHTML = "<a class='meta'>" + response.data.items[i].label + "</a>"; // create a new li element
                }
                ul.appendChild( li );// every time append a new item

            }

        })
        .catch(function (error) {
            console.log(error);
        });

Desired output:

<ul>
<li>red<li>
<li>blue
  <div>green </div>
  <div>yellow </div>
  <div>pink</div>
</li>
</ul>

Share Improve this question edited Jun 22, 2018 at 19:39 user992731 asked Jun 22, 2018 at 19:30 user992731user992731 3,5309 gold badges57 silver badges87 bronze badges 6
  • for( var i in response.data.items ){ - don't use for..in on an array, use a regular for loop - for..in is for iterating the properties of an object. – tymeJV Commented Jun 22, 2018 at 19:32
  • 1 Or use the new for ... of. – zero298 Commented Jun 22, 2018 at 19:33
  • What is the result you're looking for? – mccambridge Commented Jun 22, 2018 at 19:35
  • Just updated with desired result – user992731 Commented Jun 22, 2018 at 19:40
  • @user992731 - Please try my suggestion - a regular for loop will solve your problems – tymeJV Commented Jun 22, 2018 at 19:43
 |  Show 1 more ment

5 Answers 5

Reset to default 3

You'll want to iterate/loop over the nested items, which you aren't doing. Basically add another loop for the 2nd level of items.

Here's a cleaned up version: http://jsfiddle/DennisRas/zyn52p8v/
Note: I've removed the .axios module to show what's important.

const data = {
   "items":[
      {
         "label":"red",
         "url":"red",
         "items":[

         ]
      },
      {
         "label":"blue",
         "url":"#/blue",
         "items":[
            {
               "label":"green",
               "url":"#/green"
            },
            {
               "label":"yellow",
               "url":"#/yellow"
            },
            {
               "label":"pink",
               "url":"#/pink"
            }
         ]
      },
      {
         "label":"blue",
         "url":"#/blue",
         "items":[
            {
               "label":"green",
               "url":"#/green"
            },
            {
               "label":"yellow",
               "url":"#/yellow"
            },
            {
               "label":"pink",
               "url":"#/pink"
            }
         ]
      },
      {
         "label":"blue",
         "url":"#/blue",
         "items":[
            {
               "label":"green",
               "url":"#/green"
            },
            {
               "label":"yellow",
               "url":"#/yellow"
            },
            {
               "label":"pink",
               "url":"#/pink"
            }
         ]
      }
    ]
};

const nav = document.querySelector('nav');
const ul = document.createElement( 'ul' );

nav.appendChild(ul);

data.items.forEach(function(item) {
  const li = document.createElement('li');
  let html = "<a class='meta'>" + item.label;

  if (item.items && item.items.length) {
    item.items.forEach(function(subitem) {
        html += "<div>" + subitem.label + "</div>";
    });
  }

  html += "</a>";

  li.innerHTML = html;
  ul.appendChild(li);// every time append a new item
});

console.log(data.items);

Here's how you can do it -

var data = {
  "items": [{
      "label": "red",
      "url": "red",
      "items": [

      ]
    },
    {
      "label": "blue",
      "url": "#/blue",
      "items": [{
          "label": "green",
          "url": "#/green"
        },
        {
          "label": "yellow",
          "url": "#/yellow"
        },
        {
          "label": "pink",
          "url": "#/pink"
        }
      ]
    }
  ]
}

var createList = function(response) {
  var d = document,
    main = d.getElementById('list'),
    ul = d.createElement('ul'),
    i;

  main.appendChild(ul);

  //console.log(response.data.items);

  for (var i in response.data.items) {
    var li = d.createElement('li');
    if (response.data.items[i].items.length) {
      li.innerHTML = "<a class='meta'>" + response.data.items[i].label + "</a>"; // create a new li element
      ul.appendChild(li); // every time append a new item
      var innerul = d.createElement('ul');
      for (var j in response.data.items[i].items) {
        var innerli = d.createElement('li');
        innerli.innerHTML = "<div>" + response.data.items[i].items[j].label + "</div>"; // create a new li element
        innerul.appendChild(innerli);

      }
      li = innerul;
    } else {

      li.innerHTML = "<a class='meta'>" + response.data.items[i].label + "</a>"; // create a new li element
      ul.appendChild(li); // every time append a new item
    }
    ul.appendChild(li); // every time append a new item
  }

}

createList({
  data: data
});
<div id="list"></div>

Here's my take. You'll want to use recursion to print out the list.

function printList(list,container){
    var ul = document.createElement('ul');
    list.forEach(function(item){
        var li = document.createElement('li');
        li.innerHTML = '<div class="meta">' + item.label + '</div>';
        if(item.hasOwnProperty('items')){
            printList(item.items,li);
        }
        ul.appendChild(li);
    });
    container.appendChild(ul);
}

To use it:

axios.get('../data/colors.json').then(function (response) {
    printList(response.data.items,document.body);
})

function printList(list,container){
    var ul = document.createElement('ul');
    list.forEach(function(item){
        var li = document.createElement('li');
        li.innerHTML = '<div class="meta">' + item.label + '</div>';
        if(item.hasOwnProperty('items')){
            printList(item.items,li);
        }
        ul.appendChild(li);
    });
  container.appendChild(ul);
}

var items = {
   "items":[
      {
         "label":"red",
         "url":"red",
         "items":[

         ]
      },
      {
         "label":"blue",
         "url":"#/blue",
         "items":[
            {
               "label":"green",
               "url":"#/green"
            },
            {
               "label":"yellow",
               "url":"#/yellow"
            },
            {
               "label":"pink",
               "url":"#/pink"
            }
         ]
      }
     ]
}

printList(items.items,document.body);

console.log();

You can do this with a simple recursive function that accepts the html element you want to append to and an object. An advantage of this approach is that will work to arbitrary depths and it maintains the nesting rather than flattening everything out. Most of the work is manipulating the HTML — other than that it's a very simple idea:

let obj = {"items":[{"label":"red","url":"red","items":[]},{"label":"blue","url":"#/blue","items":[{"label":"green","url":"#/green"},{"label":"yellow","url":"#/yellow"},{"label":"pink","url":"#/pink"}]}]}

function addItems(parent, obj) {
    let keys = Object.keys(obj)
    for (key of keys) {
      let o = obj[key]      
      let li = document.createElement('li')
      if (Array.isArray(o)) {
        let text = document.createTextNode(key);
        li.appendChild(text)
        let ul = document.createElement('ul')
        o.forEach(item => addItems(ul, item))
        li.appendChild(ul)
      } else {
        li.innerText = key + ': ' + o
      }
      parent.appendChild(li)
    }
}

let list = document.getElementById('1')
addItems(list, obj)
<ul id="1">
</ul>

I don't think that you are looping over the nested items array. You are only looping over the parent array.

If there are items in the nested array, add another loop for it. For example

for (var j in response.data.items[i].items) {
  li.innerHTML = "<a class='meta'>" + response.data.items[i].label + "<div>" + response.data.items[i].items[j].label + "</div>" + "</a>"; // create a new li element
}

I think there are better patterns to do a for loop, but I am just keeping your pattern here. Basically root cause, you aren't looping over the nested items.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744368552a4570830.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信