Saturday, October 1, 2011

Be Careful Overriding ID in Backbone.js

‹prev | My Chain | next›

I think I have my Backbone.js calendar application entirely switched over to faye as the persistence layer. I can create, update, delete appointments from my calendar:
There are still a couple of minor issues that I will begin tackling tonight.

The first issue involves updating newly added appointments. At some point this month, I am going to want to get some sleep:
Much is working at this point. Backbone is able to save, via Faye. It receives confirmation. New models are created and added to a Backbone collection. And a new view is created, which places a new UI element on the calendar:
But, what if I decide that, instead of a nap, maybe it is a better idea to simply go to bed early:
Even the edit-appointment view is properly attached to the appointment-in-the-month view. But, after clicking OK to save this update, I see not one, but two admonitions to get to bed early:
Even stranger, when I reload the page, I have one nap and one early-to-bed:
The add-appointment view was not converted to a singleton view, so I give that a try. It has no effect. So I drop into the Chrome Javascript debugger:
Hrm... well, I suppose that makes sense. If the model is new, then it ought to be created when saving. But why is it new?

After quite a bit more stepping through debugger statements, I finally come across this gem in the model initializer:

          initialize: function(attributes) {
   = attributes['_id'];
I need that for initializing from the CouchDB database, but not from CouchDB updates. Ugh. I think this is another defect in my non-faye solution. Regardless, the solution is simple enough:
          initialize: function(attributes) {
   = attributes['_id'] || attributes['id'];
With that fixed, I still have a few other little things to clear out. Tomorrow.

Day #


  1. It's a lot better to override the persistence method via overriding Backbone's sync method, then you can leave the model and collection initializers alone.

    If you setup that for couch, then you can use "save" and "create" and "delete" naturally on objects and it will go through your sync method.

  2. I did override Backbone.sync -- at your earlier suggestion :)

    I am overriding initialize() so that models fetch'd from CouchDB, which have "_id" instead of "id" attributes, will work. I don't think I can avoid that when working with Couch -- can I?

    This trouble was caused because I manually set "id" in the backend for creates.