Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using JSON in Rails, Backbone and Mustache - formats seem to differ

I am trying to put together a Rails app, with backbone.js and mustache templating. I am finding that the JSON required by backbone isn't compatible with the JSON required by Mustache. (I started out following this tutorial Cloudedit -a backbone.js tutorial by example, but I want to use Mustache where he is using JST.

For backbone we must set ActiveRecord::Base.include_root_in_json = false. For my model (person with firstname and surname) the data sent by rails from /people looks like this:

[{"firstname":"Jane","surname":"Jones"},{"firstname":"Janet","surname":"Jensen"}]

My mustache template looks like this:

<h3><a href='#new'>Create New</a></h3>
<h4>People</h4>
<ul>
{{#people}}
<li>{{firstname}} {{surname}}</li>
{{/people}}
</ul>

and from the mustache docs I expect that what it wants to see is

{"people":[{"firstname":"Jane","surname":"Jones"},{"firstname":"Janet","surname":"Jensen"}]}

Edited out me transforming the JS collection back to JSON and sending to Mustache. Don't need to do that. Mustache.js expects to see js objects, not strings of JSON.

By the time I get to Mustache.to_html I have a backbone collection of models. The models have the attributes firstname and surname. It looks like this in firebug:

collection
  +_byCid
  +_byId
   length 2
  - models  [object { attributes=(...), more...}, object {attributes=(...), more...}]
    - 0 object { attributes=(...), more...}
      ....... some more properties of the object
        + attributes object {firstname="Janet", surname="Jensen"}

There seem to be a couple of problems here. 1. There is no mention of the name of the collection (people). I can get around that in various ways I guess, at least by using {{#models}}..{{/models}} in the template.

  1. The attributes are buried deeper than Mustache.js looks. When it gets down to trying to find the 'firstname' tag in the object, it looks for object['firstname'] and doesn't find it, but object.attributes['firstname'] has the correct value.

It seems I'm all mixed up here....So what am I doing wrong? And how can I fix it?

like image 491
Anita Graham Avatar asked Oct 10 '22 15:10

Anita Graham


2 Answers

I now have a solution of a sort (thanks to this question).

jsonForTemplate = JSON.parse(JSON.stringify(this.people)); //this works for a single item
context['people']=jsonForTemplate;    //need to add this for a collection
out = Mustache.to_html(tpl,context);

but it feels as though this sort of jumping-through-hoops shouldn't be necessary. I will check to see if handlebars offers anything better.

like image 165
Anita Graham Avatar answered Oct 13 '22 09:10

Anita Graham


A simpler solution would be to use toJSON on the Collection as documented here - http://documentcloud.github.com/backbone/#Collection-toJSON

out = Mustache.to_html(tpl, collection.toJSON);
like image 37
maxbeatty Avatar answered Oct 13 '22 11:10

maxbeatty