What is the right way to perform PATCH
request while saving model's attributes in Backbone.js?
[JavaScript/AJAX Code] The PATCH request method is used to modify a resource on the server partially. To send a PATCH request to the server, you need to use the HTTP PATCH method and include the request data in the body of the HTTP message.
The HTTP PATCH request method applies partial modifications to a resource. PATCH is somewhat analogous to the "update" concept found in CRUD (in general, HTTP is different than CRUD, and the two should not be confused). A PATCH request is considered a set of instructions on how to modify a resource.
Backbone no longer tries to require jQuery in Node/CommonJS environments, for better compatibility with folks using Browserify. If you'd like to have Backbone use jQuery from Node, assign it like so: Backbone.$ = require('jquery'); Bugfix for route parameters with newlines in them. 1.1.1— Feb. 13, 2014— Diff— Docs
As an example, a Rails 4 handler responding to an "update"call from Backbonemight look like this: def update account = Account.find params[:id] permitted = params.require(:account).permit(:name, :otherparam) account.update_attributes permitted render :json => account end
As of Backbone.js v0.9.9, you can simply pass { patch: true }
to save()
.
Read more: http://backbonejs.org/#changelog
In addition to James Cropchos answer I want add the following, because this stole some hours from me and maybe helps someone else:
If you use model.save(attributesToPatchObject,{patch: true})
like it is possible since backbone v.0.9.9 as stated in James Cropchos answer, you may wonder how to determine which attributes have changed since the last call of model.save()
to pass them in as attributesToPatchObject
which is the first argument from model.save()
(or model.fetch()
if you didn't save the model lately).
Backbone itself didn't keep track of those attributes. I thought the method model.changedAttributes()
could fit, but as the backbone-doc says this method returns
a hash of only the model's attributes that have changed since the last set, or false if there are none
So this method didn't fit for this need. After some research I found out that backbone itself didn't keep track of unsaved attributes (I know, not a brilliant finding if I had read the docs more carefully).
I found out that backbone.trackit is a backbone plugin which exactly add the needed feature to backbone, by adding the method unsavedAttributes()
to the model. The docs of backbone.trackit says about this method:
Symmetric to Backbone's model.changedAttributes(), except that this returns a hash of the model's attributes that have changed since the last save, or false if there are none. Like changedAttributes, an external attributes hash can be passed in, returning the attributes in that hash which differ from the model.
It works like this:
//fetch an existing model from server
model.fetch({
success : function(model, respose, options) {
//tell backbone.trackit to track unsaved Attributes
model.startTracking();
}
});
//now some changes to the model happen
model.set("someProperty", "someValue");
/* save the model to server using the PATCH-Method
and only send the unsaved Attributes;
in this case only "someProperty" is sent
*/
model.save(model.unsavedAttributes(), {patch: true});
Since the unsavedAttributes()
returns false if there are no unsaved Attributes, you could additionally wrap your save()
statement within an if-condition which checks if unsavedAttributes()
returns something other then false and only do your PATCH-Request if it's needed (because something changed).
NOTE: You didn't have to call fetch()
to use startTracking()
so you can use this method even with newly created models (model.isNew()
returns true on that model), if there is a usecase for that.
Hopes this may save someone a little bit of research time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With