Using Backbone.js with CoffeeScript

If you start writing an application using Backbone.js and Coffeescript as we did recently, you’ll quickly discover that they are both great tools. However, what you may not notice right away if you’re new to Coffeescript is that there are certain parts of Backbone’s example Todos application that become unnecessary or clunky if translated verbatim to CoffeeScript. Following are a few little things that we found made our code a bit more concise.

CoffeeScript classes

CoffeeScript provides its own syntax for declaring classes—use it. It works perfectly with the way classes are set up in Backbone and will let us use other nice features of CoffeeScript (like the instance variables below). Instead of declaring a new class using the extend method like this:


window.TodoView = Backbone.View.extend({
...

Use CoffeeScripts class and extends like this:


class window.TodoView extends Backbone.View
...

Use the power of the Fat Arrow: =>

Coffeescript will take care of binding methods to this if you declare a function using the fat arrow => instead of the skinny one ->. This means you don’t need to use _.bindAll. For example, instead of this relatively naive translation of the example application’s TodoView initialize and render methods:


initialize: ->
  _.bindAll(this, 'render', 'close')
  this.model.bind('change', this.render)
  this.model.view = this

render: ->
  $(this.el).html(this.template(this.model.toJSON()))
  this.setContent()
  return this

You can do this instead:


initialize: ->
  this.model.bind('change', this.render)
  this.model.view = this

render: =>
  $(this.el).html(this.template(this.model.toJSON()))
  this.setContent()
  return this

Use @variable instead of this.variable

If you’re like me, you’ll quickly tire of typing this.variable to get at your instance variables. Again, Coffeescript has a shorter syntax that mirror’s Ruby’s instance variable syntax that you can use. The above example becomes this:


initialize: ->
  @model.bind('change', this.render)
  @model.view = this

render: =>
  $(@el).html(this.template(@model.toJSON()))
  this.setContent()
  return this

These changes may not seem like a big deal when viewed in the limited context of a small example application, but when combined with many of the other great features provided by CoffeeScript they have cleaned up our real application’s code considerably.

 
Conversation
  • Tomasz Mazur says:


    render: =>
    $(@el).html(this.template(@model.toJSON()))
    this.setContent()
    return this

    can be simpler:


    render: =>
    $(@el).html(@template(@model.toJSON()))
    @setContent()
    @

    you don’t have to write “return” statement, because last expression is always returned in CoffeeScript (similiar to ruby)

    • Kamran Ayub says:

      I knew you could use the @ at the end and it would “return this” but personally I thought that might be a tiny bit confusing to people and it looks weird when you have a nested block before it

      classFunc: ->
          someVar = 1
          @collection.each ->
              # do some stuff
              processTask task
        
          @
      

      I prefer blank lines in-between statements (usually). Personal preference, it’s cool CoffeeScript doesn’t care.

  • […] the other stuff.How CoffeeScript makes jQuery more fun than ever.Using Backbone.js with CoffeeScript.SpaceX的航天传奇——商业公司击败举国体制的典范。 第一百八十天 […]

  • Jamie van Dyke says:

    I’m not sure, but in that last example I think you can go even further with the ‘this.’ translations:

    Forked Gist

    • Jason Porritt Jason Porritt says:

      Yes, you are correct, Jamie. As Tomasz pointed out above, we could take the ‘this.’ translations further. Interestingly, I found it felt odd at first because I’m used to seeing @ associated only with variables, not function calls. However, I am slowly getting more comfortable with @ meaning ‘this.’ in non-variable contexts.

  • Jason Miesionczek says:

    So what is your workflow for working with CoffeeScript + Backbone? What web framework do you use?

    • Jason Porritt Jason Porritt says:

      Jason, we are writing a mobile web application that communicates with a JSON API (a separate project). For the mobile web app itself we’re using Staticmatic2 to generate static assets from our Haml, Sass, and Coffeescript. The JSON API was written in .NET.

  • […] Using Backbone.js with CoffeeScript | Atomic Spin Så här snyggt blir det när du kör Backbone och CofeeScript tillsammans! […]

  • […] Using Backbone.js with CoffeeScript | Atomic Spin – […]

  • GeorgeR says:

    It would be great if you could fix the missing snippets!

  • GeorgeR says:

    Oh wait they just showed up. What.

  • Mosselman says:

    Hi, thank you for the great tips! There is one thing I got stuck on though, using the fat arrow instead of _.bindAll didn’t do the trick for me. I had some problems with ‘Cannot call ‘xyz’ of undefined when I refered to ‘this’ (or @). When I DID use _.bindAll there were no problems. It really is a shame, because in the past, before using coffeescript, I had some bugs as the result of forgetting to include or remove _.bindAll arguments.

    Despite this, the whole post is great as a quick reference to coffeescript snippets for backbone.js.

    Thanks!

  • Ryan says:

    You can also condense $(@el) to @$el which is the view’s el pre-wrapped for you.

  • Evgeny says:

    You can turn it to be a bit more idiomatic CoffeeScript,

    $(@el).html(this.template(@model.toJSON()))
    

    turns into this:

    ($ @el).html(@template @model.toJSON())
    
  • […] example uses CoffeeScript. You can see a little more about using Backbone.js and CoffeeScript in a previous […]

  • Jonah says:

    Hey just wanted to give you a quick heads up. The text in
    your content seem to be running off the screen in Firefox.
    I’m not sure if this is a formatting issue or something to do with internet browser compatibility but I thought I’d post to let you know.

    The design look great though! Hope you get the problem solved soon.
    Thanks

  • Science says:

    Hey there! I just wanted to ask if you ever have any trouble with hackers?

    My last blog (wordpress) was hacked and I ended
    up losing a few months of hard work due to no back up. Do you have any methods to protect against hackers?

  • Comments are closed.