Reputation: 503
I have written the following code in my model:
urlroot: '/url/sms',
setAuthId: function(value) {
var _this = this ;
if (this.get("smsauth") != value) {
this.set("smsauth",value);
this.save();
//Ideally, I want to achieve this AJAX call request with backbone.
// $.ajax({
// url: "/url/sms",
// data: value,
// type: 'PUT',
// processData: false,
// success: function(result) {
// _this.set("authId", value);
// },
// error : function(){
// console.log('Error setting authid');
// }
// });
}
},
Ideally, we should be firing a "PUT" request everytime. But the backbone is firing a POST request because "ID" is not present.
I'm quite new to backbone, I was wondering if there is anyway to sync with server without having to pass an ID? How can I solve this problem? I basically want to fire a PUT request NOT post request for the URL. (Since my backend only supports PUT request).
Upvotes: 2
Views: 344
Reputation: 503
I have used this snippet.
this.save({}, {
type: 'PUT'
});
I found all your answers really fascinating, I am going to try everyone of them.
Thanks for your suggestions, this is why I like SO. Something new to learn.
Upvotes: 2
Reputation: 5063
The only real way to force Backbone.Model.save()
to do a PUT
is the way @dbf
explained, you have to set your idAttribute. To properly set idAttribute
your model should have an attribute that is unique. (This is not a hard requirement, since model.isNew()
just checks that your model has a property named id
or whatever string you supply to your model idAttribute
property. It doesn't check for uniqueness).
I sense that in your case, you may not have a unique attribute in your models, so setting idAttribute
may be a challenge. For that reason, I suggest you don't specify an idAttribute
in your model definition. Rather, we just handle it dynamically.Just refactor your code like this:
setAuthId: function(value) {
var _this = this ;
if (this.get("smsauth") != value) {
// any model attribute is fine, we just need to return a prop
this.prototype.idAttribute = "smsauth"
this.save("smsauth",value) // Save will do a set before the server request
// model.save returns a promise. Here we'll reset the idAttribute
.then(/* success handler */ function (response) {
_this.set("authId",value);
_this.prototype.idAttribute = 'id' // You can set this to "authId" if that
// uniquely identifies this model
},/* error handler */ function (response) {
_this.prototype.idAttribute = 'id' // reset idAttribute to default
});
}
}
Upvotes: 3
Reputation: 3463
It's not really clear to me what you are saving. The fact you are handling with POST suggest its a new entry. Quoting from the docs this behaviour is correct. PUT is update, POST is create (under CRUD operations).
If the model isNew, the save will be a "create" (HTTP POST), if the model already exists on the server, the save will be an "update" (HTTP PUT).
What you might try is what @Sami suggest by overwriting the save with an update request (do realise that all solutions here are incorrect/workarounds).
If you really need PUT and cannot alter your backend for some mysterious reason to accept POST, you could change the idAttribute within the model.
var smsModel = Backbone.Model.extend({
idAttribute: "smsauth" // for example
});
Do realise that your backend, very likely, has a design flaw where you are changing and creating workarounds to work with it, which you should consider to avoid.
Upvotes: 2
Reputation: 4006
You can override save method
.
Something like
var model = Backbone.Model.extend({
save: function(options){
return Backbone.sync("update", this, options);
}
});
Upvotes: 0