How to process a string or array of strings in a mustache pattern

I have a simple / novice question for using mustache patterns in my application (or Hogan more precisely). I use an API that sometimes returns String and sometimes returns Array of Strings.

I know that you can bind String in a singleton array, but is there a way to handle this optionality from the mustache pattern?

Using regular sections, for example, {{#stringOrArray}} <li>{{.}}</li> {{/stringOrArray}} does not print the value if it is just a string.

+6
source share
2 answers

I know this is a little late, but here is what I use:

 {{#test.length}} {{#test}}<li>{{.}}</li>{{/test}} {{/test.length}} {{^test.length}} <li>{{test}}</li> {{/test.length}} 

This is similar to function detection. The first block of code checks to see if the test has a length, if so, it is an array (yes, I know that strings should also have a length property, but they don't). It will either output an array (if it is an array) or nothing (if it is not). The second block gives the test value if it has no length (i.e., it is a string or an integer, etc.). This means that you can use it on:

 var data = { test: "test1" } 

OR

 var data = { test: [ "test1", "test2", "test3" ] } 

without having to set a flag for whether it is an array or not. Mustache will work for you.

+11
source

I do not know how to do this directly from your object without any auxiliary variables. Here's what you CAN do before passing data to the template, to avoid having to bind to the code that generates the original JSON object.

Let it be your JSON object:

 var data = { test: [ "test1", "test2", "test3" ] } 

Let it be your mustache pattern:

 {{#isArray}} {{#test}} <li>{{.}}</li>{{/test}} {{/isArray}} {{^isArray}} {{test}} {{/isArray}} 

Let it be your code that compiles / calls your mustache pattern (I use document.body.innerHTML, because that's how I created the JSFIDDLE example):

 var template = document.body.innerHTML; document.body.innerHTML = Mustache.render(template, data); 

In the above setup, the following will be displayed: isArray is undefined, so it will execute a block that cancels isArray using the ^ character (for example, it will process the data as a string, even if it is an array):

 test1,test2,test3 

I suggest, if you do not want to touch the code that generates JSON, that you add some javascript before calling Mustache.render to set the isArray property. Here's how I would check for the existence of the pop method in order to set isArray correctly before passing data to the template:

 if (data.test.pop) { data.isArray = 1; } else { data.isArray = 0; } var template = document.body.innerHTML; document.body.innerHTML = Mustache.render(template, data); 

This will correctly print the desired li elements:

 test1 test2 test3 

I gave a working example here that uses both an array and string instances in a data element to show that the solution works:

http://jsfiddle.net/s7Wne/1/

+1
source

All Articles