Using jQuery Deferred object with SharePoint Javascript Object Model

One of the common problems with using the SharePoint client object model is the asynchronous nature of the object property calls. For example, if I want to retrieve a current user’s name, I would run code something like this:

context = new SP.ClientContext.get_current();
web = context.get_web();
currentUser = web.get_currentUser();
currentUser.retrieve();
context.load(web);
context.executeQueryAsync(
   Function.createDelegate(this, this.onQuerySucceeded),
   Function.createDelegate(this, this.onQueryFailed)
);

The executeQueryAsync method, after it retrieves the current user information, calls the onQuerySuceeded function that then completes the processing of that request. For example, something like this would be a simple example of that callback

function onSuccessMethod(sender, args) {
   var userObject = web.get_currentUser();
   alert('User name:' + userObject.get_title());
}

In between the time that the executeQueryAsync is called and the callback to the onSuccessMethod function occurs any other code that was downstream executes. This makes for awkward logic and flow in client object model programs. This is especially true when building larger applications that may want to reuse, let’s say, a function called getUserInformation which returns the current user as an object. This is where a little jQuery magic can come in handy. jQuery supports using what it refers to as Deferreds. Deferreds are based on a CommonJS Promises/A design. At the bottom of this post I will provide a link to documentation on Deferreds and the CommonJS Promise/A design, but for now let’s look at an example of how we can use this.

Let’s say I wanted to build a function like I mentioned above. A function that retrieves the current user’s information and returns that as an object. Since this request is asynchronous, this could normally be very problematic, but with a Deferred object it can be done simply. First, the initial function:
function getUserInformation() {
   var dfd = $.Deferred(function(){
      context = new SP.ClientContext.get_current();
      web = context.get_web();  
      currentUser = web.get_currentUser();  
      currentUser.retrieve();
      context.load(web);
      context.executeQueryAsync(
         function(){
            var userObject = web.get_currentUser();
            dfd.resolve(userObject);
         },
         function(){
            dfd.reject(args.get_message());
         }
      );
   });
   return dfd.promise();
}
This function creates a Deferred object, then it runs the same code as above to request the current user. The callback functions have been embedded into the executeQueryAsync method so that I can easily reference my existing Deferred object. Notice that the function itself does not return the user object. This is because when the function completes processing the user object has not yet returned. It will be return later asynchronously. Instead, the function returns a promise; a contract that there will be a return value in the future. When the callback does occur then the Deferred object is resolved and any code waiting for the object to return can execute. For illustration purposes here is a simple call to this function that creates a popup message box with the current user’s name (via the title property).
getUserInformation().done(function(user){ 
   alert('User name:' + user.get_title());
});
The nice feature with this is that if later I want to return that same user’s email address I can just as easily do that reusing the same function:
getUserInformation().done(function(user){ 
   alert('Email address:' + user.get_email());
});
To learn more about promises and Deferred objects visit these link
Advertisements
Tagged with: , ,
Posted in Javascript
One comment on “Using jQuery Deferred object with SharePoint Javascript Object Model
  1. […] how he’d explained closures also. Two blogs YOU MUST subscribe to! After a bit of digging I found this example which helped me structure my code without the […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: