Mark Mark - 1 month ago 9
Javascript Question

Cannnot overwrite Backbone save success handler

Im using backbone 1.1.0. Its been a while since I used Backbone but I'm sure I used to be able to easily overwrite the success handler for the save method. However, now i cannot seem to do it! My code is:

model.save({}, {
successs: function() {
console.log('in my custom success handler');
}
});


My custom handler doesnt not execute and the default success handler does, triggering the
sync
event.

I've looked at the question here and tried EACH of the solutions, none of which have worked. These included passing in success handler object at the third parameter, second parameter, passing in null as the first parameter etc etc etc.

The Backbone library code (v1.1.0) for the Model save method is:

save: function(key, val, options) {
var attrs, method, xhr, attributes = this.attributes;

// Handle both `"key", value` and `{key: value}` -style arguments.
if (key == null || typeof key === 'object') {
attrs = key;
options = val;
} else {
(attrs = {})[key] = val;
}

options = _.extend({validate: true}, options);

// If we're not waiting and attributes exist, save acts as
// `set(attr).save(null, opts)` with validation. Otherwise, check if
// the model will be valid when the attributes, if any, are set.
if (attrs && !options.wait) {
if (!this.set(attrs, options)) return false;
} else {
if (!this._validate(attrs, options)) return false;
}

// Set temporary attributes if `{wait: true}`.
if (attrs && options.wait) {
this.attributes = _.extend({}, attributes, attrs);
}

// After a successful server-side save, the client is (optionally)
// updated with the server-side state.
if (options.parse === void 0) options.parse = true;
var model = this;
var success = options.success;
options.success = function(resp) {
// Ensure attributes are restored during synchronous saves.
model.attributes = attributes;
var serverAttrs = model.parse(resp, options);
if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
return false;
}
if (success) success(model, resp, options);
model.trigger('sync', model, resp, options);
};
wrapError(this, options);

method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
if (method === 'patch') options.attrs = attrs;
xhr = this.sync(method, this, options);

// Restore attributes.
if (attrs && options.wait) this.attributes = attributes;

return xhr;
},


2 things puzzle me:

1/ How could it ever have been possible to overwrite the success handler(i'm sure I used to be able to do that) because when you pass in a success handler, it gets a assigned to a local var
success
, and then overridden anyway:

var success = options.success;
options.success = function(resp) {
....


2/ Why doesnt my handler also execute? It should get assigned to the local succss var:

var success = options.success;


and then executed in options.success:

if (success) success(model, resp, options);


When I debug via chrome developer tools, success is undefined. Yet I can see on the line:

var success = options.success;


that
options.success
contains my customer handler method. However the local var
success
is, somehow,
undefined
....

T J T J
Answer

I think your code should be:

model.save({}, {
  success: function(){
  //^-----this-----^
    console.log('in my custom success handler');
  }        
});