0

In the code below I can get the value of the ListItemID of a List.

var siteUrl = 'https://company.sharepoint.com/sites/demo';
var t;
 retrieveListItemsInclude();
 alert("after"+t);
function retrieveListItemsInclude() {
   var clientContext = new SP.ClientContext(siteUrl);
   var oList = clientContext.get_web().get_lists().getByTitle('My tasks');
   var camlQuery = new SP.CamlQuery();
   camlQuery.set_viewXml('<View><OrderBy><FieldRef Name="ID" Ascending ="FALSE"><RowLimit>1</RowLimit><OrderBy></View>');
   this.collListItem = oList.getItems(camlQuery);
   clientContext.load(collListItem, 'Include(Id)');
   clientContext.executeQueryAsync(onQuerySucceeded, onQueryFailed);
 alert('inside'+t);
}
function onQuerySucceeded(sender, args) {
   var listItemInfo = '';
   var listItemEnumerator = collListItem.getEnumerator();

   while (listItemEnumerator.moveNext()) {
       var oListItem = listItemEnumerator.get_current();
       listItemInfo += '\nID: ' + oListItem.get_id();
   }
t=listItemInfo;

}
function onQueryFailed(sender, args) {
   alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());

}

I need to set the value of the listItemID to a global variable e.g.t.

The variable listItemInfo is declared inside the inside onQuerySucceeded function. The scope of the listItemInfo is limited to the onQuerySucceeded function.

I need to pass it to the gobal variable.

1)Can I set the return value in OnSuccesded funcation and set it to another value.

If I add an alert inside the onQuerySucceeded() function . I get the value of the function.

I have set the value of the global variable t=listItemInfo.

When I alert the value of t inside the parent retrieveListItemsInclude() function. I get an undefined value.

I understand that the ExecuteQueryAync() function is an asynchronous function but I am facing the following issues

1) I get an undefined value after the retrieveListItemsInclude(); is called

2) If I change the call the ExecuteQueryAsync function to

clientContext.executeQueryAsync(onQuerySucceeded, onQueryFailed);

clientContext.executeQueryAsync(
        Function.createDelegate(this, this.onQuerySucceeded), 
        Function.createDelegate(this, this.onQueryFailed)
    );

3) The above code change did not make any difference but worked strangely. When I paste the code in firebug . The first time I get an undefined value but the next the value of the ID. Could this be due to caching.

What is the best way to return a value from the QuerySucceded function.

4) In IE when I edit the page the code works but when I stop editing the page it does not work. Do I need to provide the path for the SP.JS file explicitly or am I missing something

1 Answer 1

0

The reason this is happening is because of the asynchronous nature of JavaScript Client Object Model. The code execution does not wait for the onQuerySucceeded() to complete. Hence alert("after"+t); is immediately called and at this point it correctly shows undefined. However, if the same code is written afterwards at some arbitrary position in the file (And by that time assuming that onQuerySucceeded() will have completed), then it will correctly show the output. Now in order to make sure that alert("after"+t); is not executed until onQuerySucceeded() is completed, this can be done using:

  1. Using JavaScript Callbacks
  2. Using JQuery Deferreds/Promises

Example using Callbacks:

$(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
        );
};

Example using Deferreds/Promises

$(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();
};

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

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.