Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to retrieve model ID when creating new?

Using Backbone.JS, I am able to successfully create new models and save them to the server. They successfully make an ajax call and the subscribed UI elements update appropriately. The problem I then run into is that I don't know the ID of the newly created object.

I can see in the response headers for my create calls, that the sever is returning a location header like: Location https://localhost/rest/beta/mobile/footer/OTo3Njow with the last parameter being the newly created ID.

How can I get this ID without overriding backbone.sync? If I have to override backbone.sync, what is the cleanest method?

UPDATE It looks like my organization is using an older Backbone.js in which the parse method of models does not provide a reference to the XHR object, otherwise I could catch the ID and do the assigning there.

like image 439
Skylar Anderson Avatar asked Aug 25 '11 12:08

Skylar Anderson


2 Answers

The server should send back a JSON object containing the id of the model, plus any other attributes that it wants to update. If it does, Backbone will automatically grab the id.

If that's not an option, you should override Backbone.sync, because then your API (which communicates the new id in the location header instead of the response body) doesn’t conform to what Backbone supports out of the box.


If the server already does this, and you just want to get at the id, it depends on who needs to know. If it’s the code calling model.save(), then it can pass in a success callback:

model.save({}, {
    success: function(){
        // do something with model.id
    }
});

If the model itself needs to be notified when it gets an id, you can use an initializer:

var MyModel = Backbone.Model.extend({
    initialize: function(){
        this.bind("change:id", function(){
            // …
        });
    }
});
like image 83
s4y Avatar answered Nov 11 '22 22:11

s4y


I solved this by overloading the success param in backbone.sync

// Return XHR on success
params.success = function(response, text, XHR) {
  if(_.isFunction(model.xhrParse)) { model.xhrParse.call(model, response, XHR); }
  success.call(model, response);
}

and by adding a new method to my base model "xhrParse":

xhrParse: function(resp, XHR) {
   var locationHeader = XHR.getResponseHeader('Location');
   if(locationHeader && !this.id) {
     var xplode = locationHeader.split("/");
     this.id = xplode[xplode.length - 1];
   }
   return resp;
 }
like image 22
Skylar Anderson Avatar answered Nov 11 '22 23:11

Skylar Anderson