RSS Feed Feed your read!

Scot Hillier is an independent consultant and Microsoft SharePoint Most Valuable Professional focused on creating solutions for Information Workers with SharePoint, Office, and related .NET technologies. A frequent speaker at TechEd and SharePoint Connections, he is also the author many books on Microsoft technologies including 5 for SharePoint 2010. Scot splits his time between consulting on SharePoint projects and training for Critical Path Training. Scot is a former U. S. Navy submarine officer and graduate of the Virginia Military Institute. Scot can be reached at scot@shillier.com

Archives

January 2010 (17)
February 2010 (1)
March 2010 (1)
April 2010 (2)
May 2010 (1)
June 2010 (1)
August 2010 (4)
September 2010 (6)
October 2010 (3)
November 2010 (2)
February 2011 (1)
March 2011 (4)
April 2011 (3)
May 2011 (1)
August 2011 (1)
March 2012 (1)
April 2012 (1)
July 2012 (3)
August 2012 (1)
September 2012 (1)
October 2012 (2)
November 2012 (3)
January 2013 (2)
February 2013 (3)
March 2013 (3)
April 2013 (3)
May 2013 (1)

Links

Todd Baginski's Blog
BCS Team Blog
SharePoint Team Blog
SharePoint Workspace Team Blog
Andrew Connell's Blog
Ted Pattison's Blog

Tag Cloud

Apps, Books, Business Data Connectivity, Claims, Conferences, JavaScript, jQuery, MOSS 2007 Archived Post, PowerShell, REST and CSOM, Search, SharePoint 2010, SharePoint 2013, Web Content Management,

Using Promises with the JavaScript Client Object Model in SharePoint 2013 

Tags: SharePoint 2013, REST and CSOM

I’ve discussed promises briefly in a previous post and have noticed that many SharePoint developers are starting to talk about them. If promises are new to you, read that short post first to come up to speed before continuing.

Promises allow an asynchronous call to return immediately, but with a “promise” to provide the data later. Promises most naturally fit in with the SharePoint 2013 REST API because the jQuery ajax() method already returns a promise so it’s pretty straightforward. In this post, however, I want to look at using promises in the JavaScript Client Object Model (JSOM) and show that it can work there as well.

Promises can make it easy to execute dependent asynchronous calls sequentially - a common requirement in app development. For this post, I’m going to show how to use promises and JSOM to first create a SharePoint list and then add items to the list. Obviously, the list must be created before the items can be added. Even though both the list creation and the item creation are asynchronous, promises will help us execute them in the desired sequence.

Let’s start with a library for creating a new SharePoint list using JSOM.

"use strict";

 

var WingtipToys = window.WingtipToys || {};

WingtipToys.Jsom = WingtipToys.Jsom || {};

 

WingtipToys.Jsom.Lists = function () {

 

    var deferreds = new Array(),

 

    create = function (title, description, template) {

        deferreds[deferreds.length] = $.Deferred();

        var ctx = new SP.ClientContext.get_current();

        var createInfo = new SP.ListCreationInformation();

        createInfo.set_title(title);

        createInfo.set_description(description);

        createInfo.set_templateType(template);

        this.newList = ctx.get_web().get_lists().add(createInfo);

        ctx.load(this.newList);

        ctx.executeQueryAsync(

            Function.createDelegate(this,

                function () { deferreds[deferreds.length-1].resolve(this.newList); }),

            Function.createDelegate(this,

                function (sender, args) { deferreds[deferreds.length-1].reject(sender, args); }));

 

        return deferreds[deferreds.length-1].promise();

 

    };

 

    return {

        create: create

    };

 

}();

This library uses the standard ListCreationInformation object to create a new list. Notice, however, that the first line of the create function uses the jQuery $.Deferred() method to create a new deferred. The deferred object contains the promise. In the code, the new deferred object is added to an array and then the promise is returned from the asynchronous call. It’s important to understand that the promise is returned immediately - even before the asynchronous call is complete. The resolve() and reject() methods of the promise are subsequently executed when the executeQueryAsync() method completes depending upon the success or failure of the call.

Now take a closer look at the definition of the executeQueryAsync() method in the library. First, note the use of the Function.createDelegate() method to define the success and failure functions. This structure allows the definition of this to be passed into the success and failure functions. The pattern will allow us to access the newly created list after the call completes without having to save a globally-scoped variable (which is how you usually see it done). Second, notice that the resolve() method takes a parameter which references the newly-created list.

The following code can be used to call the library and create a new list.

WingtipToys.Jsom.Lists.create(

        "Announcements1",

        "A new Announcements List",

        SP.ListTemplateType.announcements).then(

 

    //create list success

    function (newList) {

        alert("Created list '" + newList.get_title() + "'");

    },

 

    //create list failure

    function (sender, args) {

        alert(args.get_message());

    }

);

In the above code, notice how the call to the create() function is made followed by the use of the then() method. The then() method fires when the asynchronous call completes and executes either the first (success) or second (failure) function as appropriate. Also notice that the success function receives the newly created list, which it then uses to display a message with the list’s title. That is pretty cool.

Now that the list is created, we want to add a list item. First, we need a library to create the list item. The following code follows the same pattern as for the list creation. A promise is returned immediately, and the newly-created list item is returned if the asynchronous call is successful.

"use strict";

 

window.WingtipToys = window.WingtipToys || {};

WingtipToys.Jsom = WingtipToys.Jsom || {};

 

WingtipToys.Jsom.ListItems = function () {

 

    var deferreds = new Array(),

 

    create = function (listName, itemTitle) {

        deferreds[deferreds.length] = $.Deferred();

        var ctx = new SP.ClientContext.get_current();

        var list = ctx.get_web().get_lists().getByTitle(listName);

        ctx.load(list);

        var listItemCreationInfo = new SP.ListItemCreationInformation();

        this.newItem = list.addItem(listItemCreationInfo);

        this.newItem.set_item("Title", itemTitle);

        this.newItem.update();

        ctx.load(this.newItem);

        ctx.executeQueryAsync(

            Function.createDelegate(this,

                function () { deferreds[deferreds.length - 1].resolve(this.newItem); }),

            Function.createDelegate(this,

                function (sender, args) { deferreds[deferreds.length - 1].reject(sender, args); }));

 

        return deferreds[deferreds.length - 1].promise();

 

    };

 

    //public interface

    return {

        create: create

    }

 

}();

Now let’s take a look at how the calls are sequenced to ensure the list is created before the item is added.

WingtipToys.Jsom.Lists.create(

    "Announcements1",

    "A new Announcements List",

    SP.ListTemplateType.announcements).then(

 

    //create list success

    function (newList) {

        alert("Created list '" + newList.get_title() + "'");

        WingtipToys.Jsom.ListItems.create(

            newList.get_title(),

            "A new announcement").then(

 

            //create item success

            function (newItem) {

                alert("Created item '" + newItem.get_id() + "'");

            },

 

            //create item failure

            function (sender, args) {

                alert(args.get_message());

            }

        );

    },

 

    //create list failure

    function (sender, args) {

        alert(args.get_message());

    }

);

Notice in the above code how the call to create a new item is nested in the success return from the list creation operation. Furthermore, notice how the returned list information is used in the subsequent call to create the list item. This is very clean and readable code that guarantees the correct sequence of events for our scenario. Even better, promises have allowed us to separate the general libraries used for list and item creation from the specific code that creates specific instances.

So it doesn’t matter if you prefer to use the SharePoint 2013 REST API or the classic JSOM approach that’s been around since 2010. Both approaches can - and should -make use of promises.

 
Posted by Scot Hillier on 4-Mar-13
0 Comments  |  Trackback Url  |  Link to this post | Bookmark this post with:        
 

Links to this post

Comments