Reputation: 447
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.
Upvotes: 1
Views: 1907
Reputation: 390
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()
Upvotes: 0
Reputation: 447
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.
Upvotes: 0
Reputation: 119
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());
}
Upvotes: 1