About the Author:

jQuery Ajax and JSON Envelopes

March 28th, 2015

This is post 3 in a series on creating a JavaScript component for handling your Ajax requests in front-end development across your enterprise. You can find all the other posts here:

In the last post we covered using the publish/subscribe pattern along with some error handling code to add some loosely coupled error messaging and load notifications. We ended with the following code for the component:

var mySiteAjax = ( function( $ ) {
var standardError = "Oops. Sorry about that. Please try again.";

return {
getViaAjax: function( params ) {
var settings = $.extend({
url: '',
spinner: undefined,
dataType: 'html',
cache: false,
success: function(){}
}, params);

var retries = 0;
function ajaxRequest ( ) {
$.ajax({
beforeSend: function(){
$(document).trigger( "ui-load-start.message",
[{ spinner: settings.spinner }] );
},
url: settings.url,
dataType: settings.dataType,
success: settings.success,
complete: function(){
$(document).trigger( "ui-load-end.message",
[{ spinner: settings.spinner }] );
},
error: function( xhr, tStatus, err ) {
if( xhr.Status === "401" || xhr.Status === "403" ) {
//redirect action here
} else if ( xhr.Status === "504" && !retries++ ) {
ajaxRequest();
}
$(document).trigger( "ui-flash.message",
[{ message: standardError }] );
} // end error handler
}); // end $.ajax()
}; // end ajaxRequest()
ajaxRequest();
} // end getViaAjax()
}; // end return statement
})(jQuery);

In this post we are going to take this code and add on some explicit functionality for handling a JSON envelope.

## What is a JSON Envelope
A JSON envelope is a wrapper around JSON returning from the server. The wrapper serves to communicate any failures or messages back to the client along with the appropriate data if the request succeeded.

Consider a scenario where you are sending the server a few parameters and hope to receive a JSON structure back. What happens if you were to send a parameter which was invalid? The server would not be able to respond with the appropriate data and a failure should be communicated.

This is different from an HTTP status code as we were able to communicate with the server successfully. We need a solution to communicate any issues which may have occurred in the server code providing a successful response to our request.

A JSON envelope is a simple mechanism to communicate messages and failures to the client as part of a JSON response. Typically the intended data for the client is wrapped in an object. The JSON object sent back to the client includes this wrapped data if successful. If not the object sent back includes a message. In all cases the response object contains a status indicator.

A typical successful JSON enveloped response might look like this:

{
"status": "ok",
"data": {
"myData": "someData"
}
}

An error response contains a status property as well as a message property indicating the issue:

{
"status": "fail",
"message": "You did not supply the correct input data."
}

Another advantage of using a JSON envelope is that the object wrapper will alleviate a subtle JSON vulnerability (outlined [here](https://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx) by Phil Haack).

### JSON Envelopes in use today

Many public services are implementing JSON envelopes for simple messages and error communication. The [Flickr API](https://www.flickr.com/services/api/) has a JSON envelope in place for simple communication of failures. You can find more information on the [JSON response format](https://www.flickr.com/services/api/response.json.html) page as well as example of [success](https://www.flickr.com/services/rest/?method=flickr.test.echo&format=json&api_key=560f2f65e11cef441ba757d2b509b157) and [failure](https://www.flickr.com/services/rest/?method=flickr.blogs.getList&format=json&api_key=560f2f65e11cef441ba757d2b509b157) responses.

## Handling a JSON Envelope

Our first step is to handle the JSON envelope in our Ajax utility component and take action if a failure occurred. If the envelope indicates a successful response we need to invoke the success callback. As a reminder from last post `settings.success` is the success callback provider by the calling code (or an empty function if none was provided):

var mySiteAjax = ( function( $ ) {
//..
$.ajax({
//...
success: function(wrapper, tStatus, xhr) {
if(!settings.type.match(/^json/i)) {
return settings.success.call( this, wrapper,
tStatus, xhr);
if(wrapper.status === "success") {
return settings.success.call( this, wrapper.data,
tStatus, xhr);
}
$(document).trigger( "ui-flash.message",
[{message: wrapper.message}] );
},
//...
});
//...
})(jQuery);

We have created a success function callback that will be run when the response returns from the server. We will inspect the envelope for a status and will take action if the status is not successful. If it is a success, we will call the success callback provided in our settings.

The code snippet `return settings.success.call( this, wrapper, tStatus, xhr);` is particularly interesting. This may be the first time you have seen the `functionName.call()` method in JavaScript. This method allows us to set the context of the `this` argument in the function call. We could have done the following:

//...
if(wrapper.status === "success") {
setting.success(wrapper.data, tStatus, xhr);
}
//...

But what is the context of `this` in that case? Probably not what the `settings.success` callback would expect. If instead we use the `functionName.call()` JavaScript function we can set the context of `this` as well as all the other arguments for the function call. This allows us to precisely supply the context expected by the `settings.success` function.

To handle the error message we added the following action:

//...
$(document).trigger( "ui-flash.message",
[{message: wrapper.message}] );
//...

We are “publishing” by using jQuery events with a custom event name. Our “message topic” indicates that there is information that should be shared with the user. It is up to another component on our page to have subscribed to this topic and to take the appropriate action. We do not have to care if the message is actually published to the user, or how it is done. We have achieved separation of concerns. Doesn’t it feel nice?

## Handling different JSON Envelopes
Different JSON envelope implementations mean different JavaScript properties and success/failure statuses to deal with. Some sites may not have a JSON envelope. Our utility component needs to handle all these cases.

To do this we will add global settings. This will allow the user to set global defaults while using arguments specified to `mySiteAjax()` if a specific call involves a different JSON envelope.

To handle global setting we will add a settings property onto our mySiteAjax object. The code snippet below is long, but bear with me. We will break it down below.

var mySiteAjax = ( function( $ ) {
var standardError = "Oops. Sorry about that. Please try again.";

// create new Ajax utility as a "private" variable
var myAjax = function( params ) {

// add together global settings with arguments
var params = $.extend({},
myAjax.settings, params);

var retries = 0;

function ajaxRequest ( ) {

$.ajax({
// publish "local" loading start message
beforeSend: function(){
$(document).trigger( "ui-load-start.message",
[{ spinner: params.spinner }] );
},
type: params.type,
url: params.url,
data: params.data,
dataType: params.dataType,
success: function(wrapper, tStatus, xhr) {

// if json is the data type and the json wrapper exists
if( (/^json/i).test(params.dataType)
&& params.env.hasEnv) {
if(wrapper[params.env.statName]
=== params.env.successInd) {

// since wrapper indicated a success,
// call original success callback with the
// unwrapped JSON contents
return params.success.call( this,
wrapper[params.env.dataName],
tStatus, xhr);
}

// success wasn't indicated, publish
// message
$(document).trigger( "ui-flash.message",
[{message: wrapper[params.env.msgName]} ] );
} else {

// return unwrapped if response wasn't json or no envelope
// was specified
return params.success.call( this, wrapper,
tStatus, xhr);
}

},

// publish "local" loading end message
complete: function(){
$(document).trigger( "ui-load-end.message",
[{ spinner: params.spinner }] );
},
error: function( xhr, tStatus, err ) {
if( xhr.Status === "401" || xhr.Status === "403" ) {
//redirect action here
} else if ( xhr.Status === "504" && !retries++ ) {
ajaxRequest();
}
$(document).trigger( "ui-flash.message",
[{ message: standardError }] );
} // end error handler
}); // end $.ajax()
}; // end ajaxRequest()
ajaxRequest();
};

// settings which are global and attached
// to the myAjax function as a property
myAjax.settings = {
url: "",
spinner: undefined,
dataType: "json",
cache: false,
type: "GET",
success: function(){},
env: {
hasEnv: true,
statName: "status",
successInd: "success",
dataName: "data",
msgName: "message"
}
};

//returns the newly created function with the properties attached.
return myAjax;

})(jQuery);

You’ll notice we moved around things. The function is now specified as a named function (although the scope is still within our component code only). We’ve also moved our settings to a property of our main utility function. Since JavaScript functions are objects augmenting it with properties is valid. You’ll also notice that we have an empty object literal as the first parameter to `$.extend()`. This is because the extend method will merge all of the object together and replace the first object with the merged results. We do not want to overwrite our global setting object each time!

Exposing our settings as a property gives us a clean way to specify defaults for a specific page. For example we can set the default HTTP action to POST with minimal effort:

myAjax.setting.type = "POST";

We’ve added settings for the JavaScript envelope. With our settings we can determine whether or not an envelope is used and how to leverage the envelope. Turning off the envelope functionality is now a one line setting:

myAjax.setting.env.hasEnv = false;

In our wrapper code we have changed the way we access objects. For example there is now this snippet:

//...
if( wrapper[params.env.statName]
=== params.env.successInd ) {
//...

Remember that we can access object properties through dot notation or bracket notation. Bracket notation allows you to specify the name of the property as a string. In our above example, with our default global setting of “success” as our status name, the code would evaluate to `wrapper[“success”]`. This would access the success property of the wrapper object. So using this piece of functionality we do not even need to know the names of the properties of our JSON object until runtime!

We now have a working Ajax Utility Component which includes a JSON envelope! I’ve set up a few examples and a playground for the component as a [jsFiddle](https://jsfiddle.net/YLKUz/1/). Please play around and ask questions in the comments!

About the Author:

EdisonJS – Organized Routing for Complex Single-Page Applications

February 11th, 2014

Over the past few years, “single-page applications” have steadily grown in popularity within the web development industry. As developers have grown accustomed to placing the bulk of the responsibility for rendering these “thick client” apps within the browser, new libraries that provide repeatable patterns for solving frequently encountered issues when using a client-heavy approach have flourished. Chief among these new libraries – JavaScript routers.

(more…)

About the Author:

Creating an Ajax Component:Handling Errors and Loading Notifications with Publish and Subscribe

September 28th, 2010
This is the second post in a multi-part series on creating a JavaScript component for handling your Ajax requests in front-end development across your enterprise. You can find the first post here:

In the last post we covered some introductory topics for creating your own JavaScript utility library, which wraps functionality for Ajax. We’ll start where we left off. Our first step will be to add a few tweaks to our library to make it more usable:

var mySiteAjax = ( function( $ ) {
  return (
     function( params ){
      var settings = $.extend({
        url: "",
        spinner:  undefined,
        dataType: "html",
        data: "",
        type: "GET",
        cache:  false,
        success:  function() { }
      }, params );
 
  $.ajax({
      beforeSend: function() {
        $( settings.spinner ).show();
      },
      url: settings.url,
      dataType: settings.dataType,
      type: settings.type,
      data: setting.data,
      success: settings.success,
      complete: function() {
          $( settings.spinner ).hide();
        }
    });
}
 

);
})(jQuery);

We’ve done two things to our old example. We’ve added new parameters for type and data that could be passed in. Additionally, we’ve removed a named function and returned an object literal. This enables easier usage:

mySiteAjax({
  url: "myUrl",
  success: function( data ) {
    //do something with the data here
  }
});

Although a good start, this solution is not yet satisfactory as we are not yet handling errors in any capacity. How do we handle errors and display messages to the user? Additionally showing and hiding of loading notification images is present but not customizable. What if a page doesn’t want to do a simple showing and hiding of load images? How can we decouple the notifications from our Ajax component library?

(more…)

About the Author:

Mock Your Ajax Requests with Mockjax for Rapid Development

July 22nd, 2010

Most backend developers are familiar with the concepts of mocking objects or stubbing in methods for unit testing. For those not familiar with mocking, it’s the simulation of an interface or API for testing or integration development purposes. Mocking with front-end development though is still quite new.

Much of the development that appendTo does focuses on front-end development tied to RESTFUL web services. As such we’re able to spec out the service contract and data format at the beginning of a project and develop the front-end interface against mock data while the back end team builds the production services.

I originally developed this plugin for appendTo back in March of this year and our team has been using it in all of our projects since. appendTo is committed to sharing our tools and best practices with the community so it’s with much excitement that we’re releasing this plugin. (A sneak peek was available to the Silicon Valley JavaScript Users Group and those that attended our OSCON tutorial)

Plugin Overview

Abstract: The mockjax plugin is a development and testing tool for intercepting and simulating ajax requests made with jQuery with a minimal impact on changes to production code.

About the Author:

Enterprise AJAX Patterns Part 1: From Enterprise Beginnings

July 17th, 2010

jQuery Ajax features provide a slick way to make asynchronous javascript calls from any browser. jQuery even gives us helpers methods to make the calls even simpler. $.get, $.getJSON, $.getScript, $.load, and $.post all give great ways to set up default features and get your ajax calls done quickly. We often see enterprise developers taking advantage of these shortcut methods for basic Ajax needs.

However, enterprises today require scalable solutions that gracefully handle errors, messages to the user, spinners, and other aspects of a rich user experience. In these series of posts we are going to step beyond the basic Ajax functionality and build a scalable library solution. In order to create a functional library you’ll need to understand the .ajax method and the parameters allowed. If you don’t already have a handle on .ajax, please visit the extremely useful api site for a quick primer.

For the purpose of these posts we are going to start with a pattern that is often seen in enterprise situations for ajax calls. In the below example we will attempt to retrieve data from the server with a GET http action via the jQuery.ajax method. (more…)