Reputation: 869
I'm calling 'save' on my model and returning the new model as json in my PHP backend. When I step through the Backbone.Model.save method, I can see that it successfully gets the server response and then sets the model (in the options.success closure below). But when the execution is returned to my click handler, the model has the old properties (ie. the id is not set). What could be happening?
Here is my click handler:
addButtonClick: function(e) {
var data = $(e.target).closest('form').serializeObject();
var p = new Domain.Page; // this extends Backbone.Model
p.set(data);
p.save();
// ****
// **** AFTER p.save, the model p still has the OLD ATTRIBUTES... why??
// ****
return false;
}
Here is Backbone's save method:
// Set a hash of model attributes, and sync the model to the server.
// If the server returns an attributes hash that differs, the model's
// state will be `set` again.
save : function(attrs, options) {
options || (options = {});
if (attrs && !this.set(attrs, options)) return false;
var model = this;
var success = options.success;
options.success = function(resp, status, xhr) {
// ****
// **** NEXT LINE SUCCESSFULLY SETS THE MODEL WITH THE SERVER RESPONSE
// ****
if (!model.set(model.parse(resp, xhr), options)) return false;
if (success) success(model, resp, xhr);
};
options.error = wrapError(options.error, model, options);
var method = this.isNew() ? 'create' : 'update';
return (this.sync || Backbone.sync).call(this, method, this, options);
},
Upvotes: 4
Views: 5895
Reputation: 869
I think I figured out what was wrong here. And Brian you were right to say it had something to do with the async nature of the Backbone.save call. The thing is that I was using the DEBUGGER. This stops all execution. I actually don't really understand how an async call works under the hood, perhaps with threads? I assumed that after I stepped over the call to 'save' and then waited a sec, then the async part (whatever that is) of the 'save' call would execute in the background. But this is not the case. The debugger halts everything. So the options.success closure within 'save' always gets called sometime after stepping over 'save'. In short, this whole thing is due to me not understanding javascript and javascript debugging properly.
Upvotes: 1
Reputation: 48127
The save
method is asynchronous. In other words, the model.set
call inside save
happens after the server has responded.
You are asking why the values are the same immediately after save
is called. The answer is: at that point in time, the response has not been received by your code yet. The callback hasn't been called. model.set
hasn't been called.
When you continue on and the event loop gets the response from the server (this may be a fraction of a second, it may be several seconds) later, your values will get set.
Upvotes: 7