Backbone model.save() is causing POST not PUT
Solution 1
Try checking user.isNew()
.
Looks like you created a new model which does not have an ID, that's why it's trying to add it during Backbone.sync
.
UPDATE:
Above is exactly true. It does POST
because it's a new model (which means, it does not have an id). Before you fetch a model, you need to give it an id. In your example:
var user = new User();
user.fetch();
user.save(); // in XHR console you see POST
var user = new User({ id: 123 });
user.fetch();
user.save(); // in XHR console you see PUT
Solution 2
if the model does not yet have an id, it is considered to be new. --http://backbonejs.org/#Model-isNew
if the model does not yet have an id, it is considered to be new... AND therefore backbone will do a PUT
request rather than a POST
.
This behavior can be overridden simply by adding type: 'POST'
to your save block:
var fooModel = new Backbone.Model({ id: 1});
fooModel.save(null, {
type: 'POST'
});
Solution 3
Use urlRoot property to set base URL /api/user
. Then
- it will POST to
/api/user
when you save a model which doesn't have_id
property set and - it will PUT to
/api/user/{_id}
when you save a model which has_id
property set. Notice that it automatically appends_id
value to the base URL.
It will look for value of _id
property because you have set that value to idAttribute
.
Solution 4
The server response must be in this way:
{
_id : 111
}
Because you set _id as the primary key. When model is fetched verify the value of _id it must have a value: console.log( model.get('_id') );
My thought is that you set in your backbone model '_id' as primary key, but service is returning you 'id'
Update: Adding sample code of normal behavior:
var UserModel = Backbone.Model.extend({
idAttribute: '_id',
url: '/api/user',
defaults:
{ username: ''
}
});
user = new UserModel({_id : 20});
user.save();
user = new UserModel();
user.save();
Output: PUT /api/user 405 (Method Not Allowed) POST /api/user 404 (Not Found)
Check how the first instance of the Model has an id and it tries to do the PUT but the other POST. I cannot reproduce your issue, so my thought is that the problem is on your server response.
Admin
Updated on July 06, 2022Comments
-
Admin almost 2 years
I have a Backbone model:
var User = Backbone.Model.extend({ idAttribute: '_id', url: '/api/user', defaults: { username: '' } });
I fetch it:
var user = new User(); user.fetch();
Now, as an
click
event in one of my views, I have this:toggleSubscription: function () { user.set('subscriptions', true); user.save(); }
This causes a POST request. However, the record already exists on the server, and since I fetched it (and the model instance has an
id
property), I thought that Backbone should do a PUT instead of a POST. Why might it be doing a POST instead?