Nugget post : using Angular JS with Mustache Templating

In a recent consolidation exersize, 6PM has decided to follow the design trend of using Google’s Material Design in it’s front-ends, and we now encourage the use of Angular JS to power these front-ends. It would seem that Angular Material (https://material.angularjs.org/latest/) is a perfect fit for this type of scenario. In many respects, it is… extremely well documented and with working code snippets, generating Material websites using familiar Angular JS directives.

However, being a complete design n00b, I quickly started hunting for Material templates that I could use, and hopefully plug in Angular Material without too much hassle. Google MDL to the rescue: Google Material Design Lite (https://www.getmdl.io/) is a fantastic and easy to use framework that let’s you get started with Material websites extremely quickly. Simple websites become really easy to build, especially with common operations like alerts, modals, cards (and not-so-common like android style toasts and snackbars!!) baked into the framework.

Since MDL doesn’t depend on any javascript frameworks, it’s very easy to simply drop in Angular Material, which I did do in some situations where MDL was unweildy (like popup menus). It’s brilliant to be able to mix and match where required.

That said, I did not want to depend on Angular JS completely, especially when it comes to building long lists of objects. Angular’s ng-repeat is notoriously slow when it comes to iterating over large lists [1]. One way of tacking this if you have predominantly static content is to render as much of the HTML page on the server. Doing this easily is where a templating engine comes in. MEAN stack developers are probably familiar with the Jade templating engine – however I am a big fan of the Moustache engine, I find it much more natural to embed logic into the HTML page – PHP / ERB style (https://mustache.github.io/).

Integrating Mustache into the MEAN stack is straightforward using “moustache-express” (https://www.npmjs.com/package/mustache-express)m and having something like the following in your package.json file:

"dependencies": {
...
"express": "~4.13.4",
 "mustache-express":"*",
...
}

However, we end up with our pages not rendering correctly. It seems like Angular JS is “switched off” as soon as we add mustache-express. This is because moustache by default uses the same delimeters as Angular uses for it’s variables – i.e. “{{” and “}}”. The solution to this is to change the delimeter used by moustache, by adding the following to the very beginning of your HTML files:

<!doctype html>
<!-- change default mustache delimiter so as not to interfere with angular-->
{{=<< >>=}}

Now we can use ERB-style delimeters to control Mustache, such as:

<title><< title >></title>

The <<title>> is now a mustache variable, which we can populate via Express by using something like:

res.render('index',  {title: 'My Demo Title'});

Resulting in:

<title> My Demo Title </title>

Since moustache supports conditionals and loops, it allows the server to pre-render the HTML page, avoiding having Angular’s ng-repeat having to do all the work (assuming you dont need to attach Angular watches to all the items in your list…)

PS – for some reason using ERB style delimiters (“<% %>”) didn’t work with mustache…. “<<” and “>>” work fine though…

References

[1] http://stackoverflow.com/questions/17348058/how-to-improve-performance-of-ngrepeat-over-a-huge-dataset-angular-js