cmcculloh
cmcculloh

Reputation: 48603

How do I save just a subset of a Backbone Model's attributes to the server without triggering a PATCH instead of a POST

The API I am hitting explodes if I send any "extra" properties back to the server. Now, I'm sure I've broken some MVC rules or something by having properties on my client side Backbone model that don't exist server side, but, what I need to do is initiate a CREATE request but only pass through some of the attributes from my model I am initiating the CREATE request from.

I can easily do this in backbone:

Model.save({key: val}, {patch: true}); 

And then modify the Backbone sync methodMap defaults patch routes to POST instead of PATCH and that nets me exactly what I'm looking for except that later on I want to actually be able to PATCH (instead of POST) when appropriate. I just need it to POST as if it were PATCHing for create actions only (not for update actions!).

So, in short, I need to take something like this:

new Backbone.Model({'foo': 'bar', 'baz': 'beh'});

And tell it to sync itself to the server, but ONLY send 'foo' across and not send 'baz', but it has to send it as a POST (it can't be a PATCH).

Any ideas?

Upvotes: 3

Views: 4243

Answers (3)

John Xiao
John Xiao

Reputation: 1838

You can override toJSON method

// set viewOnlyAttrs for attributes no need to save
viewOnlyAttrs: ['url'],

toJSON: function(options) {
  var obj = this;

  // if is calling from model's save method
  if(_.has(options || {}, 'emulateHTTP') && obj.viewOnlyAttrs)
    return _.omit(obj.attributes, obj.viewOnlyAttrs);

  return Backbone.Model.prototype.toJSON.call(this, options);
}

Upvotes: 0

Adam Alexander
Adam Alexander

Reputation: 15180

Below is a save override that can be placed in a base Backbone model or any individual model as appropriate. It may not cover every use case but it seems to fit this one.

JS Fiddle: http://jsfiddle.net/hEN88/1/

This override allows you to set a 'serverAttrs' array on any model to filter which properties are sent to the server.

save: function (attrs, options) { 
    attrs = attrs || this.toJSON();
    options = options || {};

    // If model defines serverAttrs, replace attrs with trimmed version
    if (this.serverAttrs) attrs = _.pick(attrs, this.serverAttrs);

    // Move attrs to options
    options.attrs = attrs;

    // Call super with attrs moved to options
    Backbone.Model.prototype.save.call(this, attrs, options);
}

Upvotes: 10

David Brainer
David Brainer

Reputation: 6331

This question sounds like it may be a dupe of Exclude model properties when syncing (Backbone.js) and Backbone.js/express.js parameters for model.save()

The answer in both of those cases came down to overriding the save() function.

Upvotes: 1

Related Questions