egidra
egidra

Reputation: 923

Handlebars Template not able to process JSON from Backbone

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

Upvotes: 3

Views: 12106

Answers (4)

Greg Funtusov
Greg Funtusov

Reputation: 1447

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

template(this.model.toJSON());

Upvotes: 2

Vincent Cheong
Vincent Cheong

Reputation: 142

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>

Upvotes: 1

Dan Ray
Dan Ray

Reputation: 21893

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.

Upvotes: 1

Joe
Joe

Reputation: 82554

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.

Upvotes: 10

Related Questions