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.
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();
}
getUserInformation().done(function(user){
alert('User name:' + user.get_title());
});
getUserInformation().done(function(user){
alert('Email address:' + user.get_email());
});