Aleksandr Tkachev
Aleksandr Tkachev

Reputation: 11

Handlebars.js misses JSON data

I've got template file loaded by Require.js via this:

main-app.js

define([
        'backboneLoader',
        'handlebars',
        'text!templates/main.html',
        'text!appdata.json'
    ],
    function(
        Backbone,
        Handlebars,
        MainTemplate,
        AppData
    ) {
        "use strict";

        return Backbone.View.extend({
            initialize : function() {
                this.render();
            },

            render : function() {
                var template = Handlebars.compile(MainTemplate);
                var output = template(AppData);
                this.$el.append(output);
                console.log("appData:\n" + AppData);
                console.log("MainTemplate:\n" + MainTemplate);
                console.log("Output:\n" + output);
                    //smth extra
                return this;
            }
        });
    }
);

MainTemplate (main.html)

<ul>
    <li><b>Version:</b> {{version}}</li>
    <li><b>Author:</b> {{author}}</li>
</ul>

AppData (appdata.json)

{version: "0.0.1", author: "John Doe"}

And output:

<ul>
     <li><b>Version:</b></li>
     <li><b>Author:</b></li>
</ul>

While expected output:

<ul>
        <li><b>Version:</b> 0.0.1</li>
        <li><b>Author:</b> John Doe</li>
</ul>

Any ideas what am I doing wrong? Thank you!

UPD: Problem solved. Here is updated main-app.js:

define([
        'backboneLoader',
        'handlebars',
        'text!templates/main.html!strip',
        'text!appdata.json'
    ],
    function(
        Backbone,
        Handlebars,
        mainTemplate,
        appData
    ) {
        "use strict";

        return Backbone.View.extend({
            initialize : function() {
                this.render();
            },

            render : function() {
                var template = Handlebars.compile(mainTemplate);
                var output = template(eval("(" + appData + ")")); //Object is expected by template(), not JSON.
                this.$el.append(output);
                console.log("appData:\n" + appData);
                console.log("template:\n" + mainTemplate);
                console.log("Output:\n" + output);
                    //smth extra
                return this;
            }
        });
    }
);

Upvotes: 1

Views: 645

Answers (2)

frontendbeauty
frontendbeauty

Reputation: 2129

The problem is AppData is a string of JSON, not an actual Object. Simply change from:

var output = template(AppData);

to

var output = template(JSON.parse(AppData));

You may need to include json2.js to add JSON support for older browsers (<=IE7).

Upvotes: 1

Matteo Conta
Matteo Conta

Reputation: 1449

Here is a jsFiddle repro of your template function, the template transformations seems working, the problem is probably located in the text! function in require.js code, try to debug the text! function.

Try also to add the !strip function when loading the template: 'text!templates/main.html!strip',

The documentation suggests it :For HTML/XML/SVG files, there is another option. You can pass !strip, which strips XML declarations so that external SVG and XML documents can be added to a document without worry.

Upvotes: 0

Related Questions