6

I am trying to render my nested(can be multiple level) JSON using Mustache partials. It renders only till second level it does not third & greater. As per definition partials can be used to render recursively. Am I doing it wrong ? or is there any other way to achieve the same using mustache ?

JS Bin

Template:

<script id="product-list" type="x-tmpl-mustache">
  <ul class='products'>
    {{#product}}
      <li class='product'> {{ productName }} </li>
      {{> recurse }}
    {{/product}}
    {{^product}}
      <li class='empty'> No products Available </li>
    {{/product}}
  </ul>
</script>

<script id="recursive-list" type="x-tmpl-mustache">
  <ul class='products'>
    {{#product}}
      <li class='product'> {{ productName }} </li>
    {{/product}}
  </ul>
</script>

Data:

var data = {
    product: [{
        productName: "Category1",
        product: [{
            productName: "Windows"
        }, {
            productName: "Windows Mobile"
        }]
    }, {
        productName: "Category2",
        product: [{
            productName: "SubCategory 1",
            product: [{
                productName: "Nexus 4"
            }, {
                productName: "Nexus 6"
            }]
        }, {
            productName: "SubCategory 2",
            product: [{
                productName: "ipod"
            }, {
                productName: "iphone"
            }]
        }]
    }]
};

Rendering:

$('body').html( Mustache.render( productList.html(), data, {recurse :recursiveList.html()}) );

Output (missing products: Nexus 4, Nexus 5, ipod, iphone)

Category1

 - Windows
 - Windows Mobile

Category2

 - SubCategory 1
 - SubCategory 2
Darshan
  • 750
  • 7
  • 19

1 Answers1

0

Got the solution from MustacheJS maintainer,

Working JSBin

I can just use product-list template because both product-list & recurisve-list are similar: $('body').html(Mustache.render(productList.html(), data, {recurse: productList.html()}));

If you do that, though, you'll get a maximum call stack size exceeded, which you probably wouldn't expect. It's because, by structuring your data and templates the way you did, you have created infinite recursion. In the tail products (like Nexus 4, Nexus 6, iPod, etc) the template will look for a product property and not find it. So it will walk back up the context stack, and check each level until it finds something with a product property. You can stop this by making sure the leaf products have a product property with a value like false, null or [].

New Data:

var data = {
        product: [{
            productName: "Category1",
            product: [{
                productName: "Windows",
                product: null
            }, {
                productName: "Windows Mobile",
                product: null
            }]
        }, {
            productName: "Category2",
            product: [{
                productName: "SubCategory 1",
                product: [{
                    productName: "Nexus 4",
                    product: null
                }, {
                    productName: "Nexus 6",
                    product: null
                }]
            }, {
                productName: "SubCategory 2",
                product: [{
                    productName: "ipod",
                    product: null
                }, {
                    productName: "iphone",
                    product: null
                }]
            }]
        }]
    };
Darshan
  • 750
  • 7
  • 19