Items are saved in jumbled bcoz I am using executeQueryAsync().How to make executeQueryAsync() behave synchronously?

  • Javascript implementations typically perform work asynchronously for a good reason -- because they block UI interaction if implemented synchronously. I would suggest (and what Nadeem's answer depicts below) is using a specific method of waiting for asynchronous work to correctly complete (good), rather than synchronous program behavior (bad for Javascript in the browser) – John-M Mar 17 '15 at 17:06

You can use JavaScript call backs or Promises/deferreds to work with JavaScript client object model.

CallBack Example:

$(document).ready(function () {
        //don't exectute any jsom until sp.js file has loaded.        
        SP.SOD.executeFunc('sp.js', 'SP.ClientContext', prepareTables);
    });

function prepareTables() {
    getItemsWithCaml('External User Account Request',
            function (camlItems) {
                var listItemEnumerator = camlItems.getEnumerator();
                while (listItemEnumerator.moveNext()) {
                    var listItem = listItemEnumerator.get_current();
                    console.log(listItem.get_item('Title'));
                } console.log('Completed table prparation.');
            },
            function (sender, args) {
                console.log('An error occured while retrieving list items:' + args.get_message());
            });
}    

function getItemsWithCaml(listTitle, success, error) {
    var clientContext = new SP.ClientContext.get_current();
    var list = clientContext.get_web().get_lists().getByTitle(listTitle);
    var camlQuery = new SP.CamlQuery();
    var camlItems = list.getItems(camlQuery);
    clientContext.load(camlItems);
    clientContext.executeQueryAsync(
            function () {
                success(camlItems);
            },
            error
        );
};

Promises Example

$(document).ready(function () {
        //don't exectute any jsom until sp.js file has loaded.        
        SP.SOD.executeFunc('sp.js', 'SP.ClientContext', prepareTables);
    });    

function prepareTables() {
    getItemsWithCaml('External User Account Request').then(
            function (camlItems) {
                var listItemEnumerator = camlItems.getEnumerator();
                while (listItemEnumerator.moveNext()) {
                    var listItem = listItemEnumerator.get_current();
                    console.log(listItem.get_item('Title'));
                } console.log('Completed table prparation.');
            },
            function (sender, args) {
                console.log('An error occured while retrieving list items:' + args.get_message());
            }
        );   
}    

function getItemsWithCaml(listTitle) {
    //use of $.Deferred in the executeQueryAsync delegate allows the consumer of this method to write 'syncronous like' code
    var deferred = $.Deferred();
    var clientContext = new SP.ClientContext.get_current();
    var list = clientContext.get_web().get_lists().getByTitle(listTitle);
    var camlQuery = new SP.CamlQuery();        
    var items = list.getItems(camlQuery);
    clientContext.load(items);
    clientContext.executeQueryAsync(
        Function.createDelegate(this,
            function () { deferred.resolve(items); }),
        Function.createDelegate(this,
            function (sender, args) { deferred.reject(sender, args); }));

    return deferred.promise();
};

Check this for more information: http://www.sharepointnadeem.com/2014/10/sharepoint-using-deferredspromises-or.html

  • I need to set item on success – sherin Mar 12 '15 at 5:54
  • Items are set using listItem.set_item – Nadeem Yousuf Mar 12 '15 at 5:59

@NadeemYousuf: As you probably know, both callbacks and promises are only techniques to make a code that relies on asynchronous calls more readable by hiding the asynchronicity via advanced programming constructs. However, they do not make the calls syncronous, e.g. they do not block the calling thread until a reponse is received or a timeout occurs, and that is good so.

The JSCOM is designed to work async to not block the UI thread of the browser, and there is no way to call the executeQueryAsync method synchronously, AFAIK.

There are however methods to use the JSCOM in an async manner. Note that these methods are unsupported, as they rely on internal JavaScript methods / fields of the OM.

Here is an example for SP 2010 from my blog post. The single purpose of the code is to demonstrate that it is technically possible to send synchronous HTTP requests based on the request created via JSCOM. I strongly discourage anyone to use this code in a production environment.

var title = "";

try {
   var context = SP.ClientContext.get_current();
   var web = context.get_web();
   var selectedListId = SP.ListOperation.Selection.getSelectedList();
   var selectedListItem = web.get_lists().getById(selectedListId).getItemById(itemID);
    context.load(selectedListItem, "Title");

    // start hacking
    var pendingRequest = context.get_pendingRequest();
    var webRequest = pendingRequest.get_webRequest();

    // get the request XML
    var body = pendingRequest.$24_0().toString();

    // get the URL of client.svc
    var url = webRequest.get_url();

    // "initialize" request
    SP.ClientRequest.$1T(webRequest);

    // we should add digest later to the request as an HTTP header (see below)
    var digest = webRequest.get_headers()['X-RequestDigest'];

    jQuery.ajax(
    {
        type: "POST",
        data: body,
        url: ctx.HttpRoot + url,
        success: function (result) {
            if (result.isOk != false) {
                title = result[result.length – 1].Title;
            }
        },
        headers: {
            "x-requestdigest": digest
        },
        contentType: "application/x-www-form-urlencoded",
        async: false
    });

}
catch (e) {
    alert("Error: " + e);
}
  • 1
    probably I got carried away by the term "synchronously" in the question and used the same in my answer. Thanks for pointing out that promises/callback don't actually make the calls synchronous. +1, cheers! – Nadeem Yousuf Oct 27 '16 at 10:44

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.