Backbone.js + Handlebars each

backbone.js, coffeescript, handlebars.js, ruby-on-rails, ruby-on-rails-3

Solution

Your `@collection` is, presumably, a `Backbone.Collection`. Handlebars will see it as an array of some sort so `{{entries.length}}` works as expected and `{{#each entries.models}}` iterates the right number of times; however, Handlebars has no idea what to do with the `Backbone.Model`s that are inside `@collection.models`.

Convert the `@collection` to raw data using `toJSON`, Handlebars knows what to do with simple JavaScript arrays and objects:

render: ->
    @$el.html(@template(entries: @collection.toJSON()))
    @

And then adjust your template to look at just `entries` rather than `entries.models`:

<ul>
    {{#each entries}}
        <li>{{name}}</li>
    {{/each}}
</ul>

Demo: http://jsfiddle.net/ambiguous/tKna3/

A general rule with Backbone is to pass `model.toJSON()` or `collection.toJSON()` to your templates so that they don't have to know about Backbone methods (such as `get`) and so that your templates don't accidentally alter your models and collections.

Problem

I'm trying to convert Ryan's RailsCast on Backbone.js to work with Handlebars and am stuck on a simple problem. I can't seem to be able to iterate through a JSON array and display the result. I'm using these gems in my Gemfile ``` gem 'backbone-on-rails' gem 'handlebars_assets' ``` In my `index.jst.hbs`, I have the following: ``` {{entries.length}} <ul> {{#each entries.models}} <li>{{name}}</li> {{/each}} </ul> ``` The API call seems to be working, as you can see in the count of 7 in the screenshot. However, the content of each model isn't being displayed. Here's the View (index.js.coffee) and JSON response below. ``` class Raffler.Views.EntriesIndex extends Backbone.View template: JST['entries/index'] initialize: -> #triggered when view gets created, listen to 'reset' event, then re-@render, pass 'this' for context binding @collection.on('reset', @render, this) render: -> $(@el).html(@template(entries: @collection)) this ``` JSON: ``` [ { "created_at":"2012-06-28T18:54:28Z", "id":1, "name":"Matz", "updated_at":"2012-06-28T18:54:28Z", "winner":null }, { "created_at":"2012-06-28T18:54:28Z", "id":2, "name":"Yehuda Katz", "updated_at":"2012-06-28T18:54:28Z", "winner":null }, { "created_at":"2012-06-28T18:54:28Z", "id":3, "name":"DHH", "updated_at":"2012-06-28T18:54:28Z", "winner":null }, { "created_at":"2012-06-28T18:54:28Z", "id":4, "name":"Jose Valim", "updated_at":"2012-06-28T18:54:28Z", "winner":null }, { "created_at":"2012-06-28T18:54:29Z", "id":5, "name":"Dr Nic", "updated_at":"2012-06-28T18:54:29Z", "winner":null }, { "created_at":"2012-06-28T18:54:29Z", "id":6, "name":"John Nunemaker", "updated_at":"2012-06-28T18:54:29Z", "winner":null }, { "created_at":"2012-06-28T18:54:29Z", "id":7, "name":"Aaron Patterson", "updated_at":"2012-06-28T18:54:29Z", "winner":null } ] ```

Original source