Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
71 lines (51 sloc) 3.77 KB
layout: post
title: Error handling with Ember Data
date: 2014-06-06 15:06:00
updated: 2014-06-06 15:06:00
coordinates: 50.86505 4.70068
proofread: no
<div class="narrow-col">
<p>I am building a small <a href="" title="A client side JavaScript framework">Ember</a> app for a friend, it's my first real Ember app and there is still a lot to learn. Showing validation errors when saving an <a href="" title="A data persistence library for Ember">Ember Data</a> model, for example, something that took me far longer as it should have.</p>
<p>In Ember, you can automagically access validation errors returned by the backend in your templates. <a href="" title="DS.Errors class documentation"><abbr title="Data Store">DS</abbr>.Errors</a> handles everything for you, but, documentation is sparse and every piece has to be just right for it to work.</p>
<h2>Server response</h2>
<p>Ember Data expects the server to respond in a certain way. The <abbr title="JavaScript Object Notation">JSON</abbr> response containing the error messages should include a root element with child nodes for each error. The error elements contain arrays with the error messages:</p>
{% highlight json %}
"errors": {
"email": ["can't be blank"]
{% endhighlight %}
<p>Note that Ruby on Rails does not include the <code>errors</code> root element by default so make sure to add it:</p>
{% highlight ruby %}
render json: { errors: post.errors }, status: 422
{% endhighlight %}
<p>Set your response <abbr title="Hypertext Transfer Protocol">HTTP</abbr> status code as well. I was responding with a 400 &ldquo;Bad Request&rdquo; but Ember Data only processes the error messages when it sees a 422 &ldquo;Unprocessable Entity&rdquo;, which is the correct status code by the way.</p>
<p>I was using the <a href="" title="RESTAdapter documentation">RESTAdapter</a> which doesn't include the error mapping magic out of the box. Use the <a href="" title="ActiveModelAdapter documentation">ActiveModelAdapter</a> with the <a href="" title="ActiveModel::Serializer implementation and Rails hooks">ActiveModel::Serializers</a> Ruby gem to make it work seamlessly or add <a href="">this snippet</a> to your adapter definition if you need the RESTAdapter for some reason.</p>
<h2>Saving the model</h2>
Make sure to handle errors when saving your model:
{% highlight js %} {
console.log("Post saved.");
}, function(response) {
console.error("Post not saved!");
{% endhighlight %}
<p>A simple <code></code> without promises will throw an error and stop the script execution.</p>
<code>Uncaught Error: Assertion Failed: Error: The backend rejected the commit because it was invalid: {...}</code>
<p>Finally your DS.Error object should contain all the error messages as attributes so you can access them individually.</p>
{% highlight ember %}
{% raw %}
{{#each error in}}
{% endraw %}
{% endhighlight %}
<p class="vcard">This <a class="url" href="" title="Model Errors in EmberJS">post</a> by <span class="fn">Marc Qualie</span> was extremely helpful to get me on the right track, thank you Marc!</p>