Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mustache.js recursion

I am trying to build an html tree using Mustache.js, but it fails throwning an "Maximum call stack size exceeded", probably because an infinite recursion.

What's wrong?

var Mustache = require('mustache');

var root = {
    title: 'Gar1',
    children: [{title: 'gar2'}, {title: 'gar3', children: [{title: 'gar4'}]}]
};

var panelTemplate = '{{title}}<ul>{{#children}}<li>{{>panel}}</li>{{/children}}</ul>';

var partials = {panel: panelTemplate};
var output = Mustache.render(panelTemplate, root, partials);


console.log(output);
like image 621
agori Avatar asked Nov 16 '12 00:11

agori


1 Answers

The problem is inherent to the implementation in Mustache.js (disclaimer: not sure if the problem is in the spec itself) as the algorithm looks for a property on its parent when it can't find it on the current context.

To explain it briefly: code runs on your template, outputs Gar1<ul> and finds a {{#children}} tag. Since your context has a children tag it outputs the <li> and invokes the partial which will now run on the inner context {title: 'gar2'}. When Mustache reaches your {{#children}} tag again, it now finds out that the current context has no children property, thus it goes one level up where it actually finds your children property and starts recursing (is this a real word?) again on itself like mad.

Two possible solutions:

1 - modify your data so that all entries have a children property, and when a node should have no children set it to false or null (not an empty array) like this:

var root = {
    title: 'Gar1',
    children: [{title: 'gar2', children: false}, {title: 'gar3', children: [{title: 'gar4', children: false}]}]
};

2 - use Handlebars instead of Mustache, and wrap the <ul> in an {{#if children}} tag.

Hope this helps, I know the answer is a bit late since this has been asked.

like image 110
gonchuki Avatar answered Oct 04 '22 19:10

gonchuki