Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError: Handlebars.templates is undefined

I'm working with yeoman, gruntjs and handlebars.js, but my template don't load anymore with the following error in firebug:

TypeError: Handlebars.templates is undefined
    var compiledTemplate = Handlebars.templates['cheatsheet.hbs'];

Handlebars.JS

In my package.json, I got:

"grunt-contrib-handlebars": "~0.5.9" // previously used ~0.5.8

Gruntjs tasks

Task: handlebars

I'm compiling .hbs to .hbs.js files:

handlebars: {
    compile: {
        options: {
            namespace: 'JST'
        },
        files: {
            '<%= yeoman.app %>/scripts/cheatsheet.hbs.js':
            [ '<%= yeoman.app %>/templates/{,*/}*.hbs'] ,
        }
    }
},

Task: watch

I added the following in the watch section:

watch: {
    // recompile handlebars' templates when they change
    // @see: https://github.com/yeoman/yeoman/wiki/Handlebars-integration
    handlebarsCompile: {
        files: ['<%= yeoman.app %>/templates/{,*/}*.hbs'],
        tasks: ['handlebars:compile']
    },
    handlebarsReload: {
        files: ['<%= yeoman.app %>/scripts/{,*/}*.hbs.js'],
        tasks: ['livereload']
    },

Tasks: grunt server and grunt build

I added the following entry to both task:

    'handlebars:compile',

HTML file

I'm importing handlebars, the template and the script to inflate it:

<script src="components/handlebars.js/dist/handlebars.runtime.js"></script>
<script src="scripts/cheatsheet.hbs.js"></script>
<script src="scripts/main.js"></script>

Compiled template: cheatsheet.hbs.js

In the top lines, I got this:

this["JST"]["app/templates/cheatsheet.hbs"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {

Template inflater: main.js

To inflate my compiled template I'm using this:

var compiledTemplate = Handlebars.templates['cheatsheet.hbs'];

Question

So what's the matter here Handlebars.templates array? Why is not created? How to create it?

More info

I created a gist to hold the full Gruntfile.js and cheatsheet.hbs.js.

like image 562
Édouard Lopez Avatar asked Nov 07 '25 22:11

Édouard Lopez


1 Answers

After reading the section on precompiler usage:

If using the precompiler's normal mode, the resulting templates will be stored to the Handlebars.templates object using the relative template name sans the extension. These templates may be executed in the same manner as templates.

I went on to debug the compiled template.

Debugging

Manual compilation

As I installed handlebars global, I can run compile templates manually. This wasn't enough, and I had to update the live file:

handlebars ./app/templates/cheatsheet.hbs -f ./app/scripts/cheatsheet.hbs.js # compile
cp ./app/scripts/cheatsheet.hbs.js ./.tmp/scripts/cheatsheet.hbs.js # update .tmp's template

Comparing with what grunt outputs

I saw that compiled template where different, the template reference doesn't occur in the same variable.

Manually compiled vs. Grunt compiled

- (function() {
-    var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
- templates['cheatsheet.hbs'] = template(function (Handlebars,depth0,helpers,partials,data) {
+ this["JST"] = this["JST"] || {};
+ 
+ this["JST"]["cheatsheet.hbs"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {

So I went to my task and saw

namespace: 'CHSH.Templates'

So I read the doc about namespace, and I wasn't using the right namespace in main.js

Solution

Step #1: Updating package

First globally:

sudo npm update handlebars -g

Then locally

bower update

I got some message about handlebars, but doesn't block:

Please note that requires handlebars.js ~1.0.11

Resolved to handlebars.js v1.0.0, which matches the requirement defined in the project's component.json. Conflicts may occur.

Step #2: Update Gruntfile.js

  1. I set the namespace to CHSH.Templates (cf. doc about namespace) ;
  2. I updated the files option to compile the *.hbs template from the app/templates directory to the .tmp/scripts/ and app/scripts directories;
handlebars: {
    compile: {
        options: {
            namespace: 'CHSH.Templates'
        },
        files: [{
            expand: true,
            cwd: '<%= yeoman.app %>/templates',
            src: '*.hbs',
            dest: '<%= yeoman.app %>/scripts/',
            ext: '.hbs.js'
        },
        {
            expand: true,
            cwd: '<%= yeoman.app %>/templates',
            src: '*.hbs',
            dest: '.tmp/scripts/',
            ext: '.hbs.js'
        }
        ]
    }
}

I also edited to watch task to look after scripts/{,*/}*.js.

Step #3: Update main.js

Then I updated the namespace to match what I declared in my Gruntfile.js

-    var compiledTemplate = Handlebars.templates['cheatsheet.hbs'];
+    var compiledTemplate = CHSH.Templates['app/templates/cheatsheet.hbs'];
like image 182
Édouard Lopez Avatar answered Nov 12 '25 17:11

Édouard Lopez



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!