Ember Data provides a lot of convenience when dealing with persistant objects, but in any application with a scope larger than a CRUD you'll eventually need to make an arbitrary ajax request of some kind that doesn't match up well with Ember Data.

Consider the following Ember Simple Auth authenticator:

` import Ember from 'ember' ` ` import Base from 'simple-auth/authenticators/base' ` ` import ENV from '../config/environment' ` CustomAuthenticator = Base . extend authenticate: (options) -> self = @ new Ember . RSVP . Promise (resolve, reject) -> self . makeRequest ( options ). then ( (response) -> Ember . run -> # Handle success ), (xhr, status, error) -> Ember . run -> reject xhr . responseJSON or xhr . responseText makeRequest: (data, resolve, reject) -> Ember . $ . ajax url: "/api/v1/sessions" type: 'POST' data: data dataType: 'json'

If the user doesn't successfully authenticate, we want to tell them what went wrong. For example, if they sent a blank form, they may get back something like this:

{ errors: { base: [ "Access Denied" ] , username: [ "can't be blank" ] , password: [ "can't be blank" ] } }

If this was an ember data save() call with the ActiveModelAdapter, we could use DS.Errors to handle the errors. I want to make a simple object that exposes a similar interface. Namely:

Should be able to get errors via errors.fieldName Should be able to get a list of all errors via errors.messages Both should be arrays of objects with a message property Everything should quack like an Ember Object

Getting Started on the SimpleErrors Object

For simplicity, I want to just be able to assign the json response to the SimpleErrors object, like so:

authenticate: -> self = @ @_super () . then null , (error) => self . set 'errors' , SimpleErrors . create ( error )

This will, in effect set the "errors" property on the SimpleErrors object to the JSON Response. However it will be a normal Javascript Object and not an Ember.Object. Let's fix that:

SimpleError = Ember . Object . extend init: -> @set ( 'emberized_errors' , Ember . Object . create ( @get ( 'error' )))

Now we've made another local property to hold the Ember Object equivalent of the errors object.

Getting Errors for Properties

DS.Errors exposes individual fields error messages by looking them up as properties. However we don't know ahead of time what the errors are going to be. So we need a method to lookup errors for arbitrary properties. Fortunately, ember exposes unknownProperty which works a bit like ruby's method_missing

unknownProperty: (key) -> errors = @_errorsFor ( key ) arr = Ember . A ([]) errors . map (item) -> arr . pushObject message: item arr _errorsFor: (property) -> Ember . A @get ( 'emberized_errors' ). get ( property )

Now we can look up error message associated with arbitray properties. Which means you can display property error messages just like explained in the DS.Errors documentation:

<label> Username: {{input value=username}} </label> {{#each errors.username}} <div class= "error" > {{message}} </div> {{/each}}

Displaying all messages

We still need the capability to return all error messages, for this we will use a computed property:

messages: ( -> errors = @get ( 'errors' ) allErrors = [] for own prop , value of errors allErrors = allErrors . concat errors [ prop ] @_generateMessages ( allErrors ) ). property ( 'errors' ) # Allows you to look up arbitrary errors unknownProperty: (key) -> errors = @_errorsFor ( key ) @_generateMessages ( errors ) _generateMessages: (array) -> arr = Ember . A ([]) array . map (item) -> arr . pushObject message: item arr

Here we moved generating the messages objects into it's own method, and we build a full list of errors from the errors supplied initially. Now we have the flexible interface that can be use for any arbitrary ajax call.

Another extension to this might be a fullMessages computed property that automatically prepends the property name to the message ala rails, but I'm pretty happy with this approach. The full class is below, I hope you found this useful