The discussion on stackoverflow about handling different dataType returns from AJAX calls really got me thinking about the best pattern for POSTing form data to the server.
This really ties in nicely to my previous blog post about Patterns of Organization when mixing MVC frameworks with javascript. If you are using your own RESTful API when creating a new object in your domain (a.k.a. POSTing some form to create a new foobar) what is the best pattern to follow?
Let’s first assume that you are POSTing your form via AJAX because you just popped up a lightbox that contained the form rather than doing a whole round trip to render a whole new page with the form. Therefore you have some code that looks like this:
$("form#foobar").submit(function() { $.ajax({type: 'POST', url: '/foobar', data: $(this).serializeArray(), success: function(data) { // do something with data; } }); });
Under the old MVC pattern you probably re-rendered the form if the user gave you bad data or forgot to fill out a field and then on success, you either re-directed them to the new page showing them their new data or immediately rendered that new page in the POST controller. However, in the javascript example above it becomes quite cumbersome to expect multiple possible returns. We do not want to be parsing the returned HTML to figure out if it is a re-rendered form because of a validation failure or if it is the HTML of our new item. The obvious solution is to return JSON which is easy to inspect. But I really like the idea of sending back an error HTTP response code if validation fails.
Firstly, if I am within my own application and retrieving data I do not want to write code to turn JSON into HTML. I know how I want my data to look on the page so why not just return it straight away into HTML. This allows me to keep my markup in templates where it should be. By returning validation failures as, well, failures, it allows me to instantly handle two different return types – JSON for an error code return, and HTML for a new item return. If JSON is returned I can easily pick out the error message and update the DOM of the form to display the erred fields. But if my POST was successful, I then kill the form and slide in my new HTML to update my existing list of data all nicely formatted.
Now my javascript looks something like this:
$("form#foobar").submit(function() { $.ajax({type: 'POST', url: '/foobar', data: $(this).serializeArray(), dataType: 'html', success: function(html) { $("div#data").append(html); }, error: function(XMLHttpRequest, textStatus, errorThrown) { var errorObject = JSON.parse(XMLHttpRequest.responseText); // update form with stuff in errorObject } }); });