The .save () backbone model calls POST not PUT

I have a Backbone model:

var User = Backbone.Model.extend({ idAttribute: '_id', url: '/api/user', defaults: { username: '' } }); 

I pick it up:

 var user = new User(); user.fetch(); 

Now, as a click event in one of my views, I have the following:

 toggleSubscription: function () { user.set('subscriptions', true); user.save(); } 

This causes a POST request. However, the record already exists on the server, and since I got it (and the model instance has the id property), I thought Backbone should do PUT instead of POST. Why could it be POST instead?

+7
source share
5 answers

Try checking user.isNew() .

It looks like you created a new model that does not have an identifier, so it tries to add it during Backbone.sync .

UPDATE:

The above is true. This is done by POST , because it is a new model (which means it does not have an identifier). Before you receive the model, you need to specify its 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 
+6
source

if the model does not yet have an identifier, it is considered new. - http://backbonejs.org/#Model-isNew

if the model does not yet have an identifier, it is considered new ... And so the framework will make a PUT request, not a POST .

You can override this behavior simply by adding type: 'POST' to your save block:

 var fooModel = new Backbone.Model({ id: 1}); fooModel.save(null, { type: 'POST' }); 
+2
source

Use the urlRoot property to set the base URL /api/user . Then

  • it will POST to /api/user when you save a model that has no _id property _id and
  • when you save a model that has the _id property, it will be PUT before /api/user/{_id} . Note that it automatically adds the _id value to the base URL.

It will look for the value of the _id property because you set this value to idAttribute .

+2
source

The server response should be like this:

 { _id : 111 } 

Because you set _id as the primary key. When the model is selected, check the _id value, which should have a value: console.log (model.get ('_ id'));

My thought is that you set "_id" as your primary key in your base model, but the service returns you "id"

Update : adding sample normal behavior code:

 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 identifier, and it is trying to execute PUT, but a different POST. I cannot reproduce your problem, so I believe that the problem is related to your server response.

+1
source

It might be worth checking if emulateHTTP is emulateHTTP . This will change all your PUTs in POST with the _method header _method (you can also check that this exists to confirm the idea).

0
source

All Articles