1
votes

I'm using Ember 1.2.0 and the latest Ember Data Beta and wonder, how to handle server side errors (from API calls).

This question is quite similar, but it doesn't work.

At first, the becameInvalid method doesn't triggered. I'm using ember-validations (do I have to?)

My API sends an 422 status code and responses like that:

{"errors":{"name":["has already been taken"],"initial":["has already been taken"]}}

model.js

Docket.Customer = DS.Model.extend( Ember.Validations, {
  name:        DS.attr('string'),
  initial:     DS.attr('string'),
  description: DS.attr('string'),
  validations: {
    name: {
      presence: true
    }
  },
  becameError: function() {
    alert('there was an error!');
  },
  becameInvalid: function(errors) {
    alert("Record was invalid because: " + errors);
  }
});

controller.js

Docket.OrganizationCustomersController = Ember.ArrayController.extend({

  actions: {

    save: function () {
      var customer = this.store.createRecord('customer');
      customer.set('name', this.get('name'));
      customer.set('initial', this.get('initial'));
      customer.set('description', this.get('description'));

      customer.save().then(function() {
        console.log('jeah')
      }, function() {
        console.log('nooo')
      });

    }

  }

});

The becameError method gets fired, but the becameInvalid method doesn't.

The second problem: even if the error is triggered, Ember.js adds the new record to the DOM. How can I prevent this behaviour?

2

2 Answers

1
votes

Your errors json is ok, I think you are using the DS.RESTAdapter, and it doesn't implement the becameInvalid based in json with errors.

Just DS.ActiveModelAdapter have implemented in the moment, so I recommend you to change your adapter configuration to:

Docket.ApplicationAdapter = DS.ActiveModelAdapter;
0
votes

In order to keep DS.RestAdapter, you can override its ajaxError method with the one from ActiveModelAdapter.

As for today the code, slightly adapted because some dependencies are needed, would be :

App.ApplicationAdapter = DS.RESTAdapter.extend({
    // ... your own customizations,
    ajaxError: function(jqXHR) {
        var error = this._super(jqXHR);

        if (jqXHR && jqXHR.status === 422) {
            var response = Ember.$.parseJSON(jqXHR.responseText),
                errors = {};

            if (response.errors !== undefined) {
                var jsonErrors = response.errors;

                Ember.EnumerableUtils.forEach(Ember.keys(jsonErrors), function(key) {
                    errors[Ember.String.camelize(key)] = jsonErrors[key];
                });
            }

            return new DS.InvalidError(errors);
        } else {
            return error;
        }
    }
});

Obviously you have a chance here to adapt to your backend specifics: HTTP code (422 is not a standard one) and format.

Source : http://discuss.emberjs.com/t/how-to-handle-failure-to-save-on-server/3789