17
votes

So, within one of my views, I've got this function:

delete_model: function() {
    var answer = confirm("Are you sure you want to delete this element?");
    if (answer) {
        this.model.destroy({
            success: function() {
                console.log("delete was a success");
            }
        });
    }
});

When I ping that, the Ajax call goes out, the backend properly deletes the model and returns a 200 header with "OK" as the body...but the success event never fires. Am I missing something? What should I have the backend serve to fire that event?

4
Maybe, just maybe response body should be empty. Just return 200 response code. That is how I do it. I believe that if you return anything but JSON you have got a backbone error. And just a good habit is to handle errors. - Ivan Ivanic

4 Answers

23
votes

I just had the same problem. The solution that worked for me was to make sure I return a json model from the server that corresponds to the deleted one.

edit: returning an empty json response will suffice.

Did not work:

delete(model) {
    // deleted model from db
    return "Model was deleted";
}

This did work:

delete(model) {
    // deleted model from db
    return model;
}

or:

delete(id) {
  // deleted model from db with this id
  return new Model {id: id};

}

3
votes

Had the same problem using Backbone 1.5.3 with Rails. I tried rudena's solution, and it works!

Here's what my controller's delete function looked like initially:

def destroy
  @cell = current_user.cells.find(params[:id])
  @cell.destroy

  render :json => "success"
end

And here's what worked:

def destroy
  @cell = current_user.cells.find(params[:id])
  @cell.destroy

  render :json => @cell
end
2
votes

That looks good to me, exactly what I have everywhere (except I have function(model) but that shouldn't matter at all) I do know that older versions of backbone didn't use the destroy(options) but instead had destroy(success, failure). Can you make sure you have the latest version.

0
votes

Had this problem come up with my UI as well. Upon DELETE, the API came back with an empty 200 response.

What's happening is, jQuery expects a json response body, but when the response comes back empty, json parsing fails and the error callback is triggered.

My solution was to override the Model's sync method:

var MyModel = Backbone.Model.extend({
  // Fix for empty DELETE response
  sync: function(method, model, options) {
    if (method === 'delete') {
      options.dataType = 'html';
    }
    Backbone.sync.call(this, method, model, options);
  }
});

This works because options is passed to jQuery's ajax call and we're instructing jQuery not to expect json.