6

I'm using Backbone.js on the client and node.js on the backend, and I'm having a bit of trouble doing a 'limited' model save, as explained here : http://backbonejs.org/#Model-save

As in the example, if I do

book.save({author: "Teddy"});

how do I access the parameters of the save using express.js, i.e. the fact that I only want to save to the 'author' field? I've tried the following

req.body -> gives ALL parameters of the model being saved, I want only the 'author' field
req.query -> empty

Any help much appreciated!

Petrov
  • 4,200
  • 6
  • 40
  • 61

3 Answers3

12

As stated in Model.save documentation:

save model.save([attributes], [options])
[...] The attributes hash (as in set) should contain the attributes you'd like to change — keys that aren't mentioned won't be altered — but, a complete representation of the resource will be sent to the server.

You can however override the save method and provide a data attribute via the options which will be sent to the server instead of the full model representation. For example, this will only save the attributes passed to the method :

var M = Backbone.Model.extend({   
    save: function (attrs, options) {
        options || (options = {});

        options.contentType = 'application/json';
        options.data = JSON.stringify(attrs);

        Backbone.Model.prototype.save.call(this, attrs, options);
    }
});

And a Fiddle http://jsfiddle.net/dLFgD/


As @mikebridge noted in the comments, this behavior can now be obtained by passing an attrs option. So either use

book.save(null, {
    attrs: {author: "Teddy"}
});

or keep the override

var M = Backbone.Model.extend({
    url: '/echo/json/',

    save: function(attrs, options) {
        options || (options = {});      
        options.attrs = attrs;
        Backbone.Model.prototype.save.call(this, attrs, options);
    }
});

http://jsfiddle.net/nikoshr/dLFgD/7/


You could also send a PATCH request if you're using a Backbone version that supports it (>=0.9.9) and your server understands that verb, as explained in @pkyeck's answer

Community
  • 1
  • 1
nikoshr
  • 32,926
  • 33
  • 91
  • 105
  • thanks @nikoshr i saw that but i thought there would be a way to access the parameter keys some other way... much appreciated! – Petrov Jul 17 '12 at 13:09
  • This really helped. I named this another method name so that user can call this and normal save is also preserved. – Atish Narlawar Apr 18 '13 at 04:34
  • if your server supports it, you could do a `PATCH` instead - see my [answer](http://stackoverflow.com/a/21698745/388026) – Philipp Kyeck Feb 11 '14 at 10:11
  • 2
    I think you can now accomplish this by replacing the lines setting `options.contentType=...` and `options.data = ...` with just one line: `options.attr = attrs`. This value gets used in Backbone.sync, and it takes care of the content type implicitly. – mikebridge Jun 09 '15 at 21:56
  • @mikebridge Thanks for pointing that out, I added it to my answer – nikoshr Jun 10 '15 at 08:16
3

with the current version of Backbone (1.1.0) you could also do a PATCH which only sends the changed attributes to the server.

If instead, you'd only like the changed attributes to be sent to the server, call model.save(attrs, {patch: true}). You'll get an HTTP PATCH request to the server with just the passed-in attributes.

taken from here: http://backbonejs.org/#Model-save

in your case this would be:

book.save("author", "Teddy", {patch: true});
Philipp Kyeck
  • 18,402
  • 15
  • 86
  • 123
0

The best way I have found to access POST parameters is to use the bodyParser middleware. This is referenced at this question: How to retrieve POST query parameters?

/* On startup, register the bodyParser middleware */
app.use(express.bodyParser());

/* Then, during route execution, each parameter can be accessed with req.param */
app.post('/author/:id', function(req, res) {  
  var author = req.param('author', null); // Second parameter is default.
  ...
});
Community
  • 1
  • 1
bsorbo
  • 1
  • thanks @bsorbo, the problem i was having was more how to know, on the server side (express.js), which fields had been selected to be updated by the client side (backbone.js), if i only wanted to update certain fields but not all of them. – Petrov Jul 22 '12 at 14:03