2 things I did not understand about Mustache.js

Like every time I read through a tutorial and put it in practice, I found myself once more stuck with questions I did not find the answer that easily… (I’m using Mustache.js which you can download and read about here)

Uncaught TypeError: this.tail.search is not a function

I got this error and I found it to be a bit too generic, because there are at least 3 reasons why this error might show up.

From this Stack Overflow post, 2 options come up:

  • make sure you use jQuery 2.0.1
  • if you are loading the template using AJAX, then pass it as plain text by specifying the parameter “dataType: ‘text'” for your AJAX call like so:
$.when($.ajax({url: "../data/template.mst", dataType: 'text'}),$.ajax({url: "../data/test.json"}))
.done(function(template, data){
	Mustache.parse(template[0]);
	var rendered = Mustache.render(template[0], data[0]);
	$(".container").html(rendered);
})
.fail(function(){
	alert("Sorry there was an error.");
});

At this point I still had an error and I asked for help, turns out Mustache.render() expects data to be an object and I’ve been passing an array instead.

So that from the code above I changed

var rendered = Mustache.render(template[0], data[0]);

into

var rendered = Mustache.render(template[0], {panels: data[0].panels});

I’ve probably done this mistake as my JS skills are not strong, but I expected a bit more of an explanation of where I was going wrong, considering Mustache.js does not really have that many functions (for us to use)  and a bit of error handling might be useful. I have reported this as an issue on github too. I’ve had a look through mustache.js and the documentation does not really explain that an object is expected in the render function, but it only hints to it on this line which is almost buried away:

/**
* Represents a rendering context by wrapping a view object and
* maintaining a reference to the parent context.
*/
function Context (view, parentContext) {
  this.view = view;
  this.cache = { '.': this.view };
  this.parent = parentContext;
}

So I’ve decided to submit a potential suggestion for error handling on this scenario as I don’t want other people learning Mustache to give up as I almost did if I had not had help.

I also put together a github gist with my final code, I found the examples online a bit simplistic (for example both template and data were passed to Mustache.render inline), you’ll fine at the end of this article.

Mustache.to_html or Mustache.render?

The second question I had was more a curiosity and a need to try and be a bit more consistent. I’ve seen tutorials with the method to_html() and I had render() written down in my notes as the function to put together the final HTML from the template using the data I had.

It looks like for to_html might have been deprecated, and that render is the latest solution, as suggested on this Stack Overflow post.

Looking at mustache.js once more here’s the answer:

// This is here for backwards compatibility with 0.4.x.,
/*eslint-disable */ // eslint wants camel cased function name
mustache.to_html = function to_html (template, view, partials, send) {
  /*eslint-enable*/

  var result = mustache.render(template, view, partials);

  if (isFunction(send)) {
    send(result);
  } else {
    return result;
  }
};

 

 

Here’s my final gist

Leave a Reply

Your email address will not be published. Required fields are marked *

* Copy This Password *

* Type Or Paste Password Here *