Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

backbone.js not updating id of model object after save, why not?

Tags:

backbone.js

I have been trying out backbone.js and have been stymied when I create a new model object then call model.save(). I am expecting the backbone.js default behavior to update the model object with the id from the database but it is not. Is this not supposed to happen? I have verified that I am getting a post with the attributes in json format. My server saves the json to a table and then returns the json with a new id field to backbone.js. Is this correct? Should my server return the entire new object or just the id or what?

//contents of the POST from backbone.js
  { "text":"this is a test" }

//reply from my server
  { id:"15", text:"this is a test"  }

My sample code is below

var SQLRow = Backbone.Model.extend({
 table:"",
 urlRoot:'db',
 url:function () {
    return "/" + this.urlRoot + "?table=" + this.table + 
                 "&id=" + this.attributes.id;
   }
});

var Xtra = SQLRow.extend ({
   table:'Xtra'
});

var row = new Xtra({
  text: "this is a test" 
});

alert(row.url());
row.save()
alert("row:" + row.get("id"));
like image 483
Cjolly Avatar asked May 08 '12 18:05

Cjolly


2 Answers

Tough to tell from your post. Two ideas :

1) the response from the server isn't successful What does your save call return ?

2) Your "id" attribute is named something other than ID. To account for the different name add the following to your model :

   idAttribute  : "MyModelsID",

EDIT

You're likely facing a timing issue, where the alert fires before the ID has returned. Instead of your last two lines try this :

row.save( null, 
              { 
                 success : function(model, response) { alert(model.get('id'); } 
               }
         );

ALTERNATIVE

As @mu_is_too_short mentioned, another way is to listen for the change even on the model and respond to the event. (i was just trying to keep the answer as close to your code as possible). But something like the following pseudo code should get you started...

var myView = Backbone.View.extend({
           ....
           initialize : function () {
                this.collection.bind('change',  this.SOME_LISTENING_FUNC    );

             }
  });

OR, if you're in a collection/view-less world something like this creates a listenr ...

row.on('change',  function() {  /* do stuff */ }, this);               
like image 187
EBarr Avatar answered Dec 19 '22 15:12

EBarr


This answer is based on one comment of Cjolly in the answer above.

It is essential for making the Backbone.Model.save([attributes],[options]) successful in assiging the model with the newly generated model's id from the server, that the server returns the model's id in a JSON string like this { "id" : <the id> }. (note it is "id" and not id).

In essence backbone rightly expects a JSON string and in contrast to how objects may be defined in Javascript without quoted keys, JSON requires the object keys to be quoted (see JSON Spec - does the key have to be surrounded with quotes?)

Since according to Cjolly's comment this has been the essential problem, I want to hightlight this solution in an second answer. Partially because I was hit by the very same problem and only by reading througth the comments I was able to receive the insight.

like image 21
humanityANDpeace Avatar answered Dec 19 '22 14:12

humanityANDpeace