0

How do you properly code / process 2 ExecuteQueryAsync, with the 2nd one reliant on the items of the 1st one.

Basically, I have 2 Lists. 1st List is Main List, and 2nd one is like an extension. 2nd List has column with ID of items in 1st List and additional data (kind of like a dynamic table).

What I'm trying to do is, get all Items on 1st List, and then ExecuteQueryAsync. On success, it iterates every item. It then passes the CURRENT LISTITEM ID to a 2nd function, which also ExecuteQueryAsync on the 2nd List USING THE PASSED LISTITEM ID.

However, since it is asynchronous, it seems to skip on some IDs, specifically, the 1st one; when it tries to execute 2nd function, it detects that the ListID is the 2nd one already.

I'm even using deffered, but doesn't seem to make a difference.

Below is rough code of what I have:

tryToGetAssessments().then(function (items) {
   var listEnumerator = items.getEnumerator();

   while (listEnumerator.moveNext()) {
       var listItem = listEnumerator.get_current();

       var listID = listItem.get_item('ID');
       alert(listID);
       tryToGetAssessmentsUsersTaken(listID).then(
                  function (items2) {
                      var listEnumerator2 = items2.getEnumerator();

                      while (listEnumerator2.moveNext()) {

                          var listItem2 = listEnumerator2.get_current();

                            //DO something
                      }

                  });
   }},
     function (sender, args) {
   console.log('An error occured while creating process improvement feedback:' + args.get_message());});

function tryToGetAssessments() {
        var deferred = $.Deferred();
        var clientContext = new SP.ClientContext(_spPageContextInfo.siteServerRelativeUrl + '/Articles/Assessments');
        var oList = clientContext.get_web().get_lists().getByTitle('User Assessments');
        var camlQuery = new SP.CamlQuery();
        var xml = '<View><RowLimit>0</RowLimit></View>';
        camlQuery.set_viewXml(xml);
        var listItems = oList.getItems(camlQuery);
        clientContext.load(listItems);

        clientContext.executeQueryAsync(
            Function.createDelegate(this,
                function () { deferred.resolve(listItems); }),
            Function.createDelegate(this,
                function (sender, args) { deferred.reject(sender, args); }));
        return deferred.promise();
    }

    function tryToGetAssessmentsUsersTaken(itemID) {
        alert('trying ' + itemID);
        var deferred2 = $.Deferred();
        var clientContext2 = new SP.ClientContext(_spPageContextInfo.siteServerRelativeUrl + '/Articles/Assessments');
        var oList2 = clientContext2.get_web().get_lists().getByTitle('Assessments Taken Tracker Test');
        var camlQuery2 = new SP.CamlQuery();
        var xml2 = '<View><Query><Where><Eq><FieldRef Name=\'AssessmentsIDTest\'/><Value Type=\'Number\'>' + itemID
                + '</Value></Eq></Where></Query><RowLimit>0</RowLimit></View>';
        camlQuery2.set_viewXml(xml2);
        var listItems2 = oList2.getItems(camlQuery2);
        clientContext2.load(listItems2);

        clientContext2.executeQueryAsync(
            Function.createDelegate(this,
                function () { deferred2.resolve(listItems2); }),
            Function.createDelegate(this,
                function (sender, args) { deferred2.reject(sender, args); }));
        return deferred2.promise();
    }

1 Answer 1

1

You are making it too complex with (trying to) mix Callbacks and Promises.. Drop the promise and put your second function inside the success callback of the first. It is not related or an issue, but note that Function.createDelegate is IE-version-stone-age code.

SP2013 - Failed to call, back to back executeQueryAsync() functions

Your code should look something like this: note, there are some logic errors in here, but I do not know your full code

calling function(){
    saveSubTaskStatus(subTaskId);
    updateTaskStatusAccordingly(taskId);
}

saveSubTaskStatus(subTaskId){
    clientContext.executeQueryAsync(
            onQuerySucceeded.bind(subTaskId),
            onQueryFailed
        );
}
function onQuerySucceeded(sender, args) {
    var taskId=this;//can be both a taskid and a subtaskid!! because called from 2 queries!!
    updateTaskStatusAccordingly(taskId);
    }

function updateTaskStatusAccordingly(taskId){
    clientContext.executeQueryAsync(
            onQuerySucceeded.bind(taskId),
            onQueryFailed
        );
}
2

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.