Max Schmidt
Max Schmidt

Reputation: 7665

Dealing with an empty list in mustache.js

I'm using mustache.js to render a template in javascript. I'd like to check if a list is empty or not to hide the <h2> tag in the following example. Is this possible or is mustache.js too logic-less?

This is the template:

<h2>Persons:</h2>
<ul>
  {{#persons}}
    {{name}}
  {{/persons}}
</ul>

and this is the data:

{
  "persons":[
    {"name": "max"},
    {"name": "tom"}
  ]
}

Upvotes: 34

Views: 23605

Answers (5)

iwein
iwein

Reputation: 26161

In javascript you can check with {{#names.length}}{{/names.length}} or with {{#names.0}}

If you're outside of javascript (e.g. in pystache or Scalate), you're out of luck. The only solution then is to introduce a separate boolean, or nest your array in an object which you avoid entirely if you have an empty array, like maxbeatty suggested.

Upvotes: 5

Qazzian
Qazzian

Reputation: 684

You could use persons.length. If it is a truthy value (i.e. greater than 0) then the block will be rendered.

{{#persons.length}}
<h2>Persons:</h2>
<ul>
  {{#persons}}
    <li>{{name}}</li>
  {{/persons}}
</ul>
{{/persons.length}}

Upvotes: 47

Bouke Versteegh
Bouke Versteegh

Reputation: 4677

After struggling for half a day with this problem, I've finally found an easy solution!

Don't check for the list, but check if its first item is not empty!

Template:

{{#persons.0}}
<h2>Persons:</h2>
<ul>
  {{#persons}}
    <li>{{name}}</li>
  {{/persons}}
</ul>
{{/persons.0}}
{{^persons.0}}No persons{{/persons.0}}

Data:

{
  "persons":[
    {"name": "max"},
    {"name": "tom"}
  ]
}

Output:

<h2>Persons:</h2>
<ul>
  <li>max</li>
  <li>tom</li>
</ul>

Data:

{
  "persons": []
}

Output:

"No Persons"

Upvotes: 49

Yuriy Nemtsov
Yuriy Nemtsov

Reputation: 3915

To keep your template logic-less, you can make this check before rendering the template:

// assuming you get the JSON converted into an object
var data = {
    persons: [
        {name: "max"}
      , {name: "tom"}
    ]
};
data.hasPersons = (data.persons.length > 0);

Then your template will look like this:

<h2>Persons:</h2>
{{#hasPersons}}
<ul>
  {{#persons}}
    <li>{{name}}</li>
  {{/persons}}
</ul>
{{/hasPersons}}

Upvotes: 34

andrewrk
andrewrk

Reputation: 31152

Use handlebars instead. It's a superset of Mustache which gives you that little bit more power that you need. The mustache community asked for this feature but the maintainer refuses to put it in.

Upvotes: 7

Related Questions