Handlebars Template not able to process JSON from Backbone

11,719

Solution 1

replace this function:

render: function() {
  var source = $("#round").html();
  var template = Handlebars.compile(source);
  var context = JSON.stringify(this.model);
  console.log(context);
  var html = template(context);
  $(this.el).html(html);
  return this;
},

with:

render: function() {
  var source = $("#round").html();
  var template = Handlebars.compile(source);
  var context = JSON.parse(this.model.toJSON);
  console.log(context);
  var html = template(context);
  $(this.el).html(html);
  return this;
},

template should take a javascript object in this case. JSON.stringify returns a string representation of a JSON object, not a javascript object. But what you really want are the model's attributes. So you can access those through toJSON or JSON.stringify(this.model), but then you need to convert those back into a Javascript Object.

Solution 2

Just use .toJSON() in the template call, that will transform the model attributes to a json object expected by handlebars:

template(this.model.toJSON());

Solution 3

Try:

var html = template(this.attributes);

The attributes property of the Backbone model object contains the JS object representation of the data. It's not great practice to access it directly like that, but in this case it might be the simplest thing, rather than trying to roundtrip the data through JSON.

Solution 4

I would have to agree with Dan's answer for the fastest way to do this. In the case of a list where you might need the id to capture clicks, you can even do this

<script id="round" type="text/x-handlebars-template">
{{#each friends}}
<li id="{{ this.id }}" >{{this.attributes.firstName}} {{this.attributes.lastName}}</li>
{{/each}}
</script>
Share:
11,719
egidra
Author by

egidra

Updated on June 04, 2022

Comments

  • egidra
    egidra almost 2 years

    Handlebars is unable to read the JSON object that I am sending it as context.

    Here is the function that makes the call to the Mustache template and gives it the context:

    render: function() {
      var source = $("#round").html();
      var template = Handlebars.compile(source);
      var context = JSON.stringify(this.model);
      console.log(context);
      var html = template(context);
      $(this.el).html(html);
      return this;
    },
    

    Here is the JSON object that I am passing it:

    {"result":0,"friend1":{"firstName":"Ape","lastName":"Head","fbID":329018,"kScore":99,"profilePic":""},"friend2":{"firstName":"Ape","lastName":"Hands","fbID":32,"kScore":70,"profilePic":""}}
    

    Here is the Handlebars template:

      <script id="round" type="text/x-handlebars-template">
        {{#with friend1}}
        <h2>{{firstName}} {{lastName}}</h2>
        {{/with}}
      </script>
    

    I get the following error:

    Uncaught TypeError: Cannot read property 'firstName' of undefined
    
  • egidra
    egidra over 12 years
    Hmm, it didn't seem to work. "this.model" is a Backbone object, that's why I passed the template a JSON string.
  • Joe
    Joe over 12 years
    This might seems weird but try: JSON.parse(JSON.stringify(this.model))
  • egidra
    egidra over 12 years
    Okay, I'll check you after your edit (don't know if checking blocks you from editing, so I'll wait.)