I'm having some trouble correctly forming a Backbone.Model.save call. The web service I'm calling consumes URL parameters, but what I have in Javascript is an object of changed fields. For example, I have the object {foo: 'bar', yar: 'har'}
, and I want Backbone.Model.save to send a patch request to a URL like http://server/path/to/service?foo=bar&yar=har
Sounds simple, right? It's giving me a bunch of trouble anyway. Here's what I've got so far (which doesn't work; I have success/error callbacks, too, but I don't think those are important for the question):
object =
foo: 'bar',
yar: 'har'
model.save object,
patch: true
I've tried some other options, too:
model.save object,
patch: true
emulateJSON: true
This set contentType to "application/x-www-form-urlencoded", which is good, but the data sent in the ajax request by Backbone.sync was: {model: "{"foo": "bar", "yar": "har"}". The service got that and has no idea what to do with a "model" property.
model.save object,
patch: true
contentType: "application/x-www-form-urlencoded"
This just codes object
as a string and stuffs that into options.data
. Again, the service doesn't know what to do with it.
Any other ideas on how I can get this to conform to my service's spec? I can make the ajax call myself and update the model (and the collection it belongs to) myself, but I'd really rather not do that. An ajax request that works for me is:
$.ajax
url: "http://server/path/to/service"
type: "PATCH"
data: object
Update: The reason my two earlier options didn't work is clear in Backbone.js itself:
// Ensure that we have the appropriate request data.
if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
params.contentType = 'application/json';
params.data = JSON.stringify(options.attrs || model.toJSON(options));
}
// For older servers, emulate JSON by encoding the request into an HTML-form.
if (options.emulateJSON) {
params.contentType = 'application/x-www-form-urlencoded';
params.data = params.data ? {model: params.data} : {};
}
Looking at this, I thought maybe if I stuffed the object into object into options.data
and sent in empty attributes, perhaps it'd work:
model.save {},
patch: true
data: object
Apparently this tried to PATCH an option "[object Object]". I guess it did a stringify of the object... somewhere... but this may be close to the right answer?
It looks like what I was looking for is the processData
option to jQuery.ajax
. Backbone.sync
does the following by default:
// Don't process data on a non-GET request.
if (params.type !== 'GET' && !options.emulateJSON) {
params.processData = false;
}
Thus, it wasn't processing the object into URL parameters for me. (jQuery API)
So, a working bit of code would be:
model.save {},
patch: true
data: object
processData: true
In truth, I may not be using Backbone.Model correctly overall... but, at least it's working. :P
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