Handling error feedback from Ajax requests to Rails applications

Ajax is frequently used to provide a richer user experience. Why then are important error messages rarely handled properly in Ajax enabled applications? Handling errors gracefully and in a way that helps the visitor to solve them adds a really high quality feel to your application. We've got all the necessary machinery, all it takes is a little care and attention.

class FoosController < ApplicationController
  def update
    @foo = Foo.find(params[:id])
    respond_to do |format|
      if @foo.save
        format.html do
          flash[:info] = "Your foo has been created."
          redirect_to @foo
        end
        format.js { head :ok }
      else
        format.html do
          flash.now[:warning] = "I could not update the foo."
          render :action => :edit
        end
        format.json do
          head :unprocessable_entity, :json => @foo.errors.to_json
        end
      end
    end
  end
end

Using the above code we get a lovely fallback HTML based behaviour and when we work with Ajax we get to use JSON behaviours. When JSON is requested and something goes wrong we get back an array of arrays that takes the following form.

[
  [ "attribute1", "error1", "error2" ],
  [ "attribute2", "error3"]
]

Just think of the awesome things you could do with such rich feedback...

new Ajax.Request('/foo.json', {
  method: 'PUT',
  parameters: {
    authenticity_token: window._token,
    "foo[subject]": $F('foo_subject'),
    "foo[body]"   : $F('foo_body')
  },
  onSuccess: function(transport) {
    // This is Web 2.0: celebrate with a yellow highlight.
  },
  onFailure: function(transport) {
    var errors = transport.responseJSON;
    errors.each(function(error) {
      var attribute = error.shift();
      var messages = error.join(", ");
      var errorMessage = attribute + " " + messages;
      var inputNode = $("foo_" + attribute);
      if(inputNode) {
        // Show that something is wrong with this field.
        inputNode.addClassName("error");
        // Do something better than an alert box. Alert boxes suck.
        alert(errorMessage);
      }
    });
  }
});

Related articles

Leave feedback...

Commenting is closed for this article.

About the boy

A picture of Craig in grayscale

Craig Webster is a software engineer living in London. He usually works with Ruby although sometimes he sneaks in some Erlang or JavaScript. He's into rock climbing, snowboarding, skating, photography and fencing. Yes, this does mean he has a sword.

Near here you'll find Craig's homepage, contact details, PGP key and keysigning policy, and talks.

Licence

The entire content of this blog is public domain. Use it however you fancy. You don't even need to attribute it to me, although it would be nice if you did. Just don't sue me and we'll all be happy.

I Work With Rails

Recommend Me

My Travels

I go places. Do you go places too? Let's meet up!.