0

For some odd reason, Backbone is trying to put my model object instead of posting it to the server.

The error is an HTTP 500 error because Backbone is trying to put a model with no id (because I have made it undefined):

 PUT /api/teams/undefined 500 285ms - 135b

Here's my code:

this.model.id = undefined;
this.model._id = undefined;
teamCollection.add(this.model);
this.model.save(null,
    {
        success: function (model) {

            $('.top-right').notify({
                message: {text: ' New team added!  '},
                type: 'info',
                fadeOut: {
                    delay: 3500
                }
            }).show();
            window.userHomeMainTableView.render();
        }
        ,
        error: function (model) {
            teamCollection.remove(model);
            $('.top-right').notify({
                message: {text: ' Error adding team :(  '},
                type: 'danger',
                fadeOut: {
                    delay: 3500
                }
            }).show();
        }
    });

even after "forcing" the model.id and model._id to be undefined, Backbone still tries to do an HTTP PUT. How can this be?

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817

3 Answers3

3

The syncing process internally uses Model#isNew to decide if it should PUT or POST. isNew is very simple minded:

isNew model.isNew()

[...] If the model does not yet have an id, it is considered to be new.

and that check is done using:

!this.has(this.idAttribute)

The has method is just a simple wrapper around attr:

has: function(attr) {
  return this.get(attr) != null;
}

so these are irrelevant:

this.model.id = undefined;
this.model._id = undefined;

when Backbone is deciding to PUT or POST, those don't really remove the id attribute, they break your model.

I think you'd be better off copying the model (without the id) and saving the copy:

var data = m.toJSON();
delete data.id;
var copy = new Model(data);

Or better, create a whole new model, populate it with data, and then save the new model instance.

I think you'd need to unset the id attribute and manually remove the id property to make what you're trying to do work.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • well, I defined my idAttribute in my model as _id, so setting _id should affect it, right – Alexander Mills Mar 14 '15 at 06:56
  • 1
    If you have an `idAttribute: '_id'` then you'd want to `m.unset('_id')` and `delete m.id`. But still, what you're trying to do looks a bit odd to me, it looks like you're trying to re-use an existing model instance when you should be creating a new one. – mu is too short Mar 14 '15 at 13:26
  • nope, I am sending a new model object to the new view instance, that's why it's so beffuddling – Alexander Mills Mar 14 '15 at 21:49
  • If it is a new model then why does it have an `id`? The `id` is supposed to come from the server when you save the new model. – mu is too short Mar 14 '15 at 22:51
  • 1
    `var copy = new Model(_.omit(m.attributes, m.idAttribute));` would avoid using `toJSON` and the need to delete the id. – Emile Bergeron Dec 12 '16 at 02:22
1

that's strange it looks like it should do a POST from your code. It looks like you can ovverride it though. From the second answer here

fooModel.save(null, {
  type: 'POST'
});
Community
  • 1
  • 1
actual_kangaroo
  • 5,971
  • 2
  • 31
  • 45
-1

use the following code snippet to set the id to undefined.

this.model.set('id',undefined');

although if it's a new model you don't need to do this. it will be undefined by default. if you have used the idAttribute for defining the model and say it's value is userId then you need to do something like this.

this.model.set('userId',undefined');
rakesh
  • 129
  • 4