6

Is there proper way to handle custom error when saving a model? To give an example, lets say I have a model with just two properties "name" and "value". And when I do :

var myModel = this.get('store').createRecord('myModel', {"name": "someName", "value": "someValue"});
myModel.save().then(function() {
    //if success
    //server responded with {"myModel:{"id":1,"name":"someName","value":"someValue"}"}
},function() {
    //if failure
    //server responded with {"error":"some custom error message"}
    //BUT HOW TO CATCH THIS AND POSSIBLY REMOVE THE MODEL FROM THE STORE

});

One way to work around this is to make extra ajax call to check if the name is unique and then do the save. I am just wondering what is the best/elegant approach here.

Thanks, Dee

EDIT : I thought it might help a bit to give more context on the server side of the things in groovy. So here it is:

In my controller I have :

def create() {

    try {
        newRow = someService.create(params)
        render someService.list(newRow) as JSON//returns data in format needed by ember-data
    }
    catch (ValidationException ex) {
        def errors = ["errors":[]]

        ex.errors.allErrors.each{
            if(it.arguments[0] == "fieldName" && it.code=="constrantViolated"){
                errors.errors.push(["field":it.arguments[0],"message":"some custom message"])
            }
        }
        //I am using 422 here because of post in http://stackoverflow.com/questions/7996569/can-we-create-custom-http-status-codes
        render(status: 422, contentType: 'JSON', text: (errors as JSON))
    }

}

Then in my ember controller:

    var myModel = self.get('store').createRecord('myModel ', myModelDataInJSON);
myModel .save().then(function () {
        //if success
                },
    function (response) {
        myModel .deleteRecord();
        var errors = $.parseJSON(response.responseText);
        for (var key in errors.errors) {
            //do something
        }
    });
Deewendra Shrestha
  • 2,313
  • 1
  • 23
  • 53

3 Answers3

8

deleteRecord will delete the record.

myModel.save().then(function(response) {
  //if success
  //server responded with {"myModel:{"id":1,"name":"someName","value":"someValue"}"}
},function(response) {
  //if failure
  //server responded with {"error":"some custom error message"}
  //BUT HOW TO CATCH THIS AND POSSIBLY REMOVE THE MODEL FROM THE STORE
  if(response.error=='no good'){
    myModel.deleteRecord();
  }

});
Kingpin2k
  • 47,277
  • 10
  • 78
  • 96
  • Thanks. I was initially having issue with how to get response.error but later I figured out how to send response text with proper HTTP error code and get the responseText instead. – Deewendra Shrestha Oct 25 '13 at 15:24
  • 2
    That's how I do for the moment as well but I don't like that it starts to show the record and remove it once the server answered. Is there a way to wait for the server answer to display the persisted record? – Bachet Nov 13 '13 at 18:22
2

You can handle errors at model by adding properties into your model:

becameError: ->
  # handle error case here
  alert 'there was an error!'

becameInvalid: (errors) ->
  # record was invalid
  alert "Record was invalid because: #{errors}"

Check: How should errors be handled when using the Ember.js Data RESTAdapter?

Community
  • 1
  • 1
0

Why wouldn't the answer be to just use the: DS.ERRORS CLASS?

From EmberJS docs:

For Example, if you had an User model that looked like this:

App.User = DS.Model.extend({ username: attr('string'), email: attr('string') });

And you attempted to save a record that did not validate on the backend.

var user = store.createRecord('user', {
  username: 'tomster',
  email: 'invalidEmail'
});
user.save();

Your backend data store might return a response that looks like this. This response will be used to populate the error object.

{
  "errors": {
    "username": ["This username is already taken!"],
    "email": ["Doesn't look like a valid email."]
  }
}

Errors can be displayed to the user by accessing their property name or using the messages property to get an array of all errors.

{{#each errors.messages}}
  <div class="error">
    {{message}}
  </div>
{{/each}}

Is this question only focused on validation into the model? versus persistence/saving it, hence data is clean already before it hits a data store... Seems like you would still want error management at the adapter data store level, too.

That all said, why wouldn't you just use template or normal based JS validation at the UI control level?

DavidK
  • 11
  • 1
  • The question arose because I had no idea how to grab the server side errors that might pop out when saving the question. Yes we do validate the model before we save the model, but sometimes the server may be down or there are certain validation which can only be done in the server level(such as checking uniqueness etc) and we just wanted to show those errors in the UI. I am currently doing something very similar to what you have suggested - so that all server side errors and client side errors are always pushed to same array and not much needs to be changed in UI to show the errors. Thanks. – Deewendra Shrestha Jul 30 '14 at 16:52
  • I see... What is the architecture of your server side? Is it a Ruby on Rails environment with a sql type based database that ultimately all data is being stored? Or something simpler - Rest --> Firebase? – DavidK Jul 31 '14 at 15:21
  • Here's where the above text came from for reference http://emberjs.com/api/data/classes/DS.Errors.html – artburkart Aug 14 '14 at 17:14