1

Here is my snippet code below.My aim is to simply loop through item ids and update the list in batches. I need help with using CSOM to do this I need this as currently when i send a batch of over 800 items i get timeout. Thanks in Advance

var items;
var oList;
var oListItem
function getItemsToBeUpdated() 
{

  $('#lblprogress').text("Updating items please wait.... ");
  $('#lblprogress').show();


    var siteUrl = '/sites/MySite';


    var clientContext = new SP.ClientContext(siteUrl);
    //var clientContext = new SP.ClientContext.get_current();

     oList = clientContext.get_web().get_lists().getByTitle('PTest');

    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml('<View><Query></Query><RowLimit>100</RowLimit></View>');
    items = oList.getItems(camlQuery);
    clientContext.load(items);    
    clientContext.executeQueryAsync(updateMultipleListItemsSuccess, updateMultipleListItemsFailed);


   //This works but i need to send 17 items(using the itemid and then 13 items out of 30 for example etc..)
    for (var i = 1; i <= 17; i++) {

        this.oListItem = oList.getItemById(i);

        oListItem.set_item('Update', 'Force');

        oListItem.update();

        clientContext.executeQueryAsync(updateMultipleListItemsSuccess, updateMultipleListItemsFailed);


    }

    /*for (var i = 15; i <= 30; i++) {

        this.oListItem = oList.getItemById(i);

        oListItem.set_item('Force_x0020_Update', 'Force Update');

        oListItem.update();

        clientContext.executeQueryAsync(updateMultipleListItemsSuccess, updateMultipleListItemsFailed);


    }*/

}

//I can get the id here and use it onSucess but when i try updating here it doesnt work
function getID() {

   var itemEnumerator = items.getEnumerator();
    while(itemEnumerator.moveNext()){
        var item = itemEnumerator.get_current();

        // You now have the item you were looking for!
         console.log(item.get_item("ID"));

    } 


}


function updateMultipleListItemsSuccess() {

   getID();

    $('#lblprogress').text("Items Updated Successfully");
    //alert('Items Updated');
    $('#reset').show();



}

    function updateMultipleListItemsFailed(sender, args) 
    {    

     $('#lblprogress').hide();
     $('#lblerror').text('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
     $('#reset').show();

    }

2 Answers 2

1

What you need to know first is that you can pass an array of items to clientContext.load method, and keep in mind that backend will still return a timeout response if you send hundreds items for update.

So the idea is to build an array of items within a loop (one loop is enough) and to load ever x items.

Here's a code that should work, and at least help you understand:

var IDs = [1, 31, 32]; // List of our item IDs
var itemsToLoadForUpdate = Array(); // Holds our "current" items to update
var totalItemsToUpdate = 800;
var limitItemsToUpdate = 90; // Update every 90 items
var batchUpdatesCounter = Math.ceil(totalItemsToUpdate / limitItemsToUpdate); // If you need to count the remaining batch updates
var restItemsToUpdate = 0; // Items to update after (see below)
for(var i=0;i<IDs.length;i++) {
    var oListItem = oList.getItemById(IDs[i]);
    oListItem.set_item('Update', 'Force');
    oListItem.update();
    itemsToLoadForUpdate[i] = oListItem;
    clientContext.load(itemsToLoadForUpdate[i]);
    if(i && i % limitItemsToUpdate == 0) {
        console.log('Updating '+ limitItemsToUpdate +' items...');
        clientContext.executeQueryAsync(this.onUpdateSucceeded, this.onUpdateFailed);
        restItemsToUpdate = 0;
    }
    else { // Remaining items to update
        restItemsToUpdate = i % limitItemsToUpdate;
    }
}
if(restItemsToUpdate) {
    console.log('Updating rest items...');
    clientContext.executeQueryAsync(this.onUpdateSucceeded, this.onUpdateFailed);
}

In your onUpdateSucceeded method you may use batchUpdatesCounter variable to check wheter all updates were performed by decreasing it every time that method is called.

6
  • Thanks Salah will give it a shot. Just one more question what is this the IDs representing
    – naijacoder
    Commented Nov 28, 2018 at 1:30
  • I've updated the code sample. IDs is an array that contains your items IDs, you may use a fonction or whatever to retrieve items IDs for update.
    – Salah
    Commented Nov 28, 2018 at 6:36
  • Thanks Salah. I have one more issue getting the IDs . I couldn't get an array values returned from the asyc delegate function. Is there a way to do this?
    – naijacoder
    Commented Dec 2, 2018 at 23:09
  • I cannot understand what you're exactly trying to do. Please do post a new question.
    – Salah
    Commented Dec 3, 2018 at 12:37
  • Thanks Salah. How can i dynamically receive the item IDs here :- var IDs = [1, 31, 32]; // List of our item IDs as in the code above?
    – naijacoder
    Commented Dec 3, 2018 at 22:23
0

I think you are looking for bulk update method to update your item.

function BulkUpdate() {
    var dfd = $.Deferred();
    //Get list from host web   
    var PTest = appCtx.get_web().get_lists().getByTitle('PTest');
    var camlQuery = newSP.CamlQuery();
    camlQuery.set_viewXml('<View><Query></Query><RowLimit>100</RowLimit></View>');
    //Get items by Query  
    var progColl = PTest.getItems(camlQuery);
    //Load item collection  
    context.load(progColl);
    context.executeQueryAsync(function () {
        varcurrentItemArray = [];
        //Check itemcollection count greater than 0  
        if (progColl.get_count() > 0) {
            varprogEnum = progColl.getEnumerator();
            while (progEnum.moveNext()) {
                var currentItem = progEnum.get_current();
                var currentId = currentItem.get_item("ID");
                //Get Item by current ID  
                var items = PTest.getItemById(currentId);
                items.set_item('Update', 'Force');
                //Update the item  
                items.update();
                //Push item on the array  
                currentItemArray.push(items);
                //Load the item Array  
                context.load(currentItemArray[currentItemArray.length - 1]);
            }
            context.executeQueryAsync(function () {
                //Item Updated sucess  
                alert("Items are updated Successfully");
                dfd.resolve();

            }, function (sender, args) {
                    //Item updated fail  
                    console.log("Request Failed to get projectlist Items :" + args.get_message());
                });
        } else {
            dfd.resolve();
        }
    },
        function (sender, args) {
            $('.loader').hide();
            console.log("Request failed in Portfolio List " + args.get_message());
        });
    return dfd.promise();
}
2
  • Thanks Negi.Will this update more than 800 items asi have approached a similar approach and it failed :(
    – naijacoder
    Commented Dec 4, 2018 at 6:28
  • you need to send a bech request
    – Negi Rox
    Commented Dec 5, 2018 at 6:03

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.