While using mustache.js, I wanted to return the rendered result from mustache to a callback function instead of simply filling any element’s innerHTML directly.
Just to make it easier for some of the people like me – and to have this code easily available for myself later – I am writing this short how-to.
If you like this content and found it helpful, please consider supporting me with a small donation.
So what is the problem?
On the project’s github page, the maker of mustache.js shows us how to use mustache.js with jQuery to render external template files and displaying the content directly on the page.
function loadUser() { $.get('template.mst', function(template) { var rendered = Mustache.render(template, {name: "Luke"}); $('#target').html(rendered); }); }
Bit I didn’t want this behaviour for several reasons.
So I needed to return the rendered template file content to the calling method. But a simple return would not help here, as we are working with jQuery.ajax – which works asynchronously.
So what to do? How do I get the rendered template back to my “main” method?
How to solve this?
We’re going to use a callback function to pass the results back to the calling function. :)
Build the view file.
This file resides in /views , where all my view/ mustache template files will be located. So the path to this file is /views/test.mst .
<div> <h5>This is the view file</h5> Name: {{name}}<br /> Age: {{age}}<br /> </div>
The index.html
This is the main index.html file, in which we’re loading jQuery, mustache.js and our own little app.js.
It also includes a button with the id show , on which we will register an event listener, as well as a div with the class result .
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <button id="show">Show Data</button> <div class="result"> </div> <script src="js/jquery-1.12.0.min.js"></script> <script src="js/mustache.min.js"></script> <script src="js/app.js"></script> </body> </html>
app.js
The app.js file holds all the logic. Here is the code – below it, I will explain what it does in detail.
var app = { data: { name: "Chris", age: "39" }, displayData: function () { app.renderTemplate("test", app.data, function (returnValue) { $('.result').append(returnValue); }); }, renderTemplate: function (templatefile, data, callback) { var tpl = 'views/' + templatefile + '.mst'; $.ajax(tpl, { dataType: "text", success: function (template) { var rendered = Mustache.render(template, data); callback(rendered); } }); } }; $(document).ready(function () { $('#show').on('click', function () { app.displayData(); }); });
We’re creating an object called app , which holds the data and method needed to show the rendered mustache templates.
At first, we are creating the app.data object, which holds the properties name and age .
The app.displayData method will be called when the button#show is clicked. It simply calls the app.renderTemplate method with the needed parameters templatefile (String which holds the template file name) and data (Object which holds the data to render into the template).
The method also provides a callback function, which in return gets the returnValue back from the app.renderTemplate method once it completes.
Once the callback function is called, it will simply append() the returnValue to the element $(‘.result’) .
The app.renderTemplate method first builds the var tpl , which is simply a string representing the template file path. This step could be omitted and directly done within the $.ajax method, but I like it this way as it is easier to read (at least for me).
The method then uses the jQuery.ajax method to get the contents of the template file. It is important to use dataType: “text” , as this will get the contents as plain text instead of XMLDocument, as has happened to me before…
Within the success function of the ajax method, we call mustache.render() to render the data into the template. The returned content will be in the variable rendered , which is then sent to the callback function.
The function will also receive the Store or the Router object if the associated option was passed in during render.