Question

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

    }
Était-ce utile?

La solution

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.

Autres conseils

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();
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à sharepoint.stackexchange
scroll top