Using jQuery Callbacks to find out when an async web service call is complete

Mar 1, 2012 at 7:51 PM
Edited Mar 1, 2012 at 8:08 PM

Callbacks were added to jQuery in version 1.7. I found a handy use for them in combination with SPServices. So, I thought I would post here for anyone interested.

My particular use case is as follows. I have a form that pulls data from 5 different web services asynchronously. Some of them are SharePoint (using SPServices) and some of them are not. I want to be able to do a bunch of stuff when each web service call is successfully completed. For example, in one case I want to get rid of the loading panel, display the data and save portions of the data to a SharePoint list. Here is how I handle it.

First, I setup the callbacks "Status" function (note that this is only slightly modified from the jQuery documentation)

var statuses = { };

jQuery.Status = function(id) {
    var callbacks,
        status = id && statuses[id];
    if (!status) {
        callbacks = jQuery.Callbacks();
        status = {
            publish: callbacks.fire,
            subscribe: callbacks.add,
            unsubscribe: callbacks.remove
        };
        if (id) {
            statuses[id] = status;
        }
    }
    return status;
};

Next, I  setup the subscribers. Each subscriber is a separate function and listens for when "GotTheMotts" is published. You could (I haven't done this yet) reuse each subscriber (like RemoveLoadingPanel) for each data call and just pass in a parameter to tell it which loading panel to remove.

$.Status("GotTheMotts").subscribe(RemoveLoadingPanel);
$.Status("GotTheMotts").subscribe(DisplayData);
$.Status("GotTheMotts").subscribe(SaveData);

Next, I make a web service call to a SharePoint list (note that this is wrapped in a function that does other stuff but I just copied the SPServices call here). This call just gets the "ID" of a list item based on the "queryParam" CAMLQuery (which isn't shown here). Note that in the completefunc, I have a line that publishes "GotTheMotts". This basically lets the listeners know that the call is complete and it was successful. Each of the listeners then runs its attached function (RemoveLoadingPanel, DisplayData, and SaveData).

        $().SPServices({
            operation: "GetListItems",
            async: true,
            listName: "Name of List",
            CAMLQuery: queryParam,
            CAMLViewFields: "<ViewFields>" +
            "<FieldRef Name='ID' />" +
            "</ViewFields>",
            completefunc: function(xData, status) {
                window.listItemId = $(xData.responseXML).find("z\\:row").attr("ows_ID");
                 $.Status("GotTheMotts").publish();
            }
        });

Coordinator
Mar 12, 2012 at 1:56 AM

Doug:

Just wanted to let you know that I haven't forgotten about this. I want to try it out and at least use it in the docs. It also may make a good blog post if you don't mind me borrowing the code. With credit, of course!

M.