Javascript nested loop

I do not code much in Javascript, but I have the following snippet which IMHO looks horrendous and I have to do this nested iteration quite often in my code. Does anyone have a prettier/easier to read solution?

function addBrowse(data) {
var list = $('<ul></ul>')

for(i = 0; i < data.list.length; i++) {
    var file = list.append('<li class="toLeft">' + data.list[i].name + '</li>')
    for(j = 0; j < data.list[i].children.length; j++) {
        var db = file.append('<li>' + data.list[i].children[j].name + '</li>')
        for(k = 0; k < data.list[i].children[j].children.length; k++)
            db.append('<li class="toRight">' + data.list[i].children[j].children[k].name + '</li>')
    }
}

$('#browse').append(list).show()}

Here is a sample data element

  • Formatting of JavaScript for MVC3 views
  • How many checks against null is appropriate?
  • Is it a good practice to use $parent in angular?
  • JavaScript pushing an object in an array is what - by reference or value?
  • Javascript document write overwriting page?
  • Elegant way of checking if a value is within a range and setting it's value if it falls outside of the range?
  • {"file":"","db":"","tbl":"","page":"browse","list":[
      {
         "name":"/home/alex/GoSource/test1.txt",
         "children":[
            {
               "name":"go",
               "children":[
                  {
                     "name":"validation1",
                     "children":[
    
                     ]
                  }
               ]
            }
         ]
      },
      {
         "name":"/home/alex/GoSource/test2.txt",
         "children":[
            {
               "name":"go",
               "children":[
                  {
                     "name":"validation2",
                     "children":[
    
                     ]
                  }
               ]
            }
         ]
      },
      {
         "name":"/home/alex/GoSource/test3.txt",
         "children":[
            {
               "name":"go",
               "children":[
                  {
                     "name":"validation3",
                     "children":[
    
                     ]
                  }
               ]
            }
         ]
      }]}
    

    Thanks a lot

  • Batch code indenters and beautifiers
  • Confused by how many ways there are to set NODE_ENV
  • How do I add style to content in JavaScript?
  • js style properties returns blank
  • Is there a recommended maximum line length for HTML or JavaScript?
  • Why use semicolon?
  • 4 Solutions collect form web for “Javascript nested loop”

    It might be better to look into a JavaScript templet engine:

    You can use jQuery’s each() function to make this look nicer:

    function addBrowse(data) {
      var list = $('<ul></ul>')
    
      $.each(data.list, function(_, item) {
        var file = list.append('<li class="toLeft">' + item.name + '</li>');
        $.each(item.children, function(_, child) {
          var db = file.append('<li>' + child.name + '</li>');
          $.each(child.children, function(_, grandchild) {
            db.append('<li class="toRight">' + grandchild.name + '</li>');
          });
        });
      });
    
      $('#browse').append(list).show();
    }
    

    A problem here, though, is that you introduce XSS vulnerabilities. You can use jQuery’s text function to avoid that, though. Or, as Detroitpro points out, use a templating engine. Also, beware of performance implications when using $.each – it’s slower than a for loop, but that won’t matter much unless you do it many times.

    it would be tempting to put the two inner loops in their own functions. This would simplify the code by removing all those nested children references. Although the function calls would cost time, a lot of array referencing would be removed, so you’ll probably end up square. more importantly it would be simpler code.

    If you’re using jQuery, it has a fiew methods that can help you out:

    function addBrowse(data) {
        var list = $(document.createElement('ul')),
            li = $(document.createElement('li')),
            get_li;
    
        get_li = function(value, className) {
            className = className === undefined ? '' : className;
            return li.clone().text(value).addClass(className);
        };
    
        $.each(data.list, function (i, v) {
            list.append(get_li(v.name, 'toLeft'));
            $.each(v.children, function(i, v2) {
                list.append(get_li(v2.name));
                $.each(v2.children, function(i, v3) {
                    list.append(get_li(v3.name, 'toRight'));
                });
            });
        });
        $('#browse').append(list).show();
    }