1

I am trying to add 5000 items in a SharePoint list using JSOM. But unfortunately didn't get any luck.

function createListItem() {
    var clientContext = new SP.ClientContext.get_current();
    var oList = clientContext.get_web().get_lists().getByTitle('DummyList');

    var itemCreateInfo = new SP.ListItemCreationInformation();
    for (var i = 0; i < 5000; i++) {
        this.oListItem = oList.addItem(itemCreateInfo);

        oListItem.set_item('ItemNumber', i);
        oListItem.update();
    }

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

function onQuerySucceeded() {
    console.log('Item created: ' + oListItem.get_id());
}

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

But after some time server stops responding. I know there is something called Threshold limit. But according to the requirement more than 5000 items should be stored in one take only. I have no idea where I am making mistake. Please help.

Chandan Rauniyar
  • 814
  • 1
  • 14
  • 24
Harsh Jaswal
  • 447
  • 3
  • 14

3 Answers3

1

Here is a suggestions. It does work on my environnements. It takes some times though (around 20 seconds) because all requested are queued by the server. You can probably play around with the batch limit to optimize numbers of requests.

function createListItem() {
    var clientContext = new SP.ClientContext.get_current();
    var oList = clientContext.get_web().get_lists().getByTitle('DummyList');

    var items = [];
    var batchLimit = 100;

    for (var i = 0; i < 5000; i++) {
        var itemCreateInfo = new SP.ListItemCreationInformation();
        var newItem = oList.addItem(itemCreateInfo);

        newItem.set_item('ItemNumber', i);
        newItem.update();
        items[i] = newItem;
        clientContext.load(items[i]);

        if (i % batchLimit == 0) {
            console.log("sending batch" + i / batchLimit);                                
            clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
            items = [];
        }            
    }
}

function onQuerySucceeded() {
    console.log('Item created');
}

function onQueryFailed(sender, args) {
    console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
Julien
  • 101
  • 2
  • 12
  • Thanks for the response [Julien](https://stackoverflow.com/users/7310601/julien). I tried with REST API and it is working now. – Harsh Jaswal Dec 11 '17 at 09:36
  • Great you've found a solution. I also tend to make REST API my first choice. I suggested a solution with jsom because your initial post was using it. In this case, it's also interesting because you can send batches and reduce the number of request from 5000 to 50 or less... – Julien Dec 11 '17 at 10:35
0

Somehow I found the solution for this. Instead of call back method I used REST API like this

function RestAdd()
{

      for(var i = 0 ; i < 5000; i++)
      {
$.ajax  
    ({  
    url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbytitle('DummyListForMultiAdd')/items",  
    type: "POST",
    async: false,
    data: JSON.stringify  
    ({  
        __metadata:  
        {  
            type: "SP.Data.DummyListForMultiAddListItem"  
        },  
        ItemNumber: i
    }),  
    headers:  
    {  
        "Accept": "application/json;odata=verbose",  
        "Content-Type": "application/json;odata=verbose",  
        "X-RequestDigest": $("#__REQUESTDIGEST").val(),  
        "X-HTTP-Method": "POST"  
    },  
    success: function(data, status, xhr)  
    { 
    console.log("success: "+i);
    },  
    error: function(xhr, status, error)  
    {  
        console.log("failed: "+i);
    }  
});
}
}

What I did is, I just used REST API with async:false. It adds your list items in a sync manner. In JSOM it works in async.

Harsh Jaswal
  • 447
  • 3
  • 14
0

Here is a combination of the two techniques.

async function createListItem() {
  const url = `${_spPageContextInfo.webAbsoluteUrl}/_api/web/lists/getbytitle('DummyListForMultiAdd')/items`;
  for (let index = 0; index < data.length; index += 100) {
    const finalNumber = index + 100 < data.length ? index + 100 : data.length;
    const batch = data.slice(index, finalNumber);
    const batchPromises = batch.map((d, i) => {
      d.__metadata = {
        type: "SP.Data.DummyListForMultiAddListItem"
      };
      d.ItemNumber = i + index;
      return xhr("post", url, d);
    })
    await Promise.all(batchPromises);
  }

  function xhr(type, url, data) {
    const prom = new Promise((res, rej) => {
      const xhr = new XMLHttpRequest();
      xhr.onreadystatechange = () => {
        if (xhr.readyState === XMLHttpRequest.DONE) {
          try {
            if (xhr.status === 200 || xhr.status === 201) {
              res(xhr.responseText);
            } else {
              const {
                status
              } = xhr;
              const name = "XHRError";
              const message =
                xhr.responseText ||
                "An error occured in sending or recieving the request";
              throw {
                status,
                name,
                message
              };
            }
          } catch (error) {
            if (error.status) {
              rej(error);
            } else {
              rej({
                status: 418,
                name: error.name,
                message: error.message
              });
            }
          }
        }
      };
      xhr.open(type, url);
      [{
          key: "Accept",
          value: "application/json;odata=verbose"
        },
        {
          key: "Content-Type",
          value: "application/json;odata=verbose"
        },
        {
          key: "X-RequestDigest",
          value: document.querySelector("#__REQUESTDIGEST").value
        }
      ].forEach(h => xhr.setRequestHeader(h.key, h.value));
      xhr.send(JSON.stringify(data));
    });
    return prom;
  }
}
createListItem()
Joshua Rose
  • 370
  • 2
  • 10