6

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

1
  • 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
    Commented Mar 17, 2015 at 17:06

2 Answers 2

10

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

2
  • I need to set item on success
    – sherin
    Commented Mar 12, 2015 at 5:54
  • Items are set using listItem.set_item Commented Mar 12, 2015 at 5:59
4

@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
  • 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! Commented Oct 27, 2016 at 10:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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