Reputation: 21
Hopefully somebody can show me a way to do this, and explain why this code is failing. I believe it is a scope issue but have banging my head on it for a few days.
Let me first explain what the code is doing. I have a HTML button on a web part aspx page that runs a function in a js file. The code searches my Sharepoint list for items that are missing two field values, via a CAML query. It then loops through the items, and calls an asynchronous web service for each item. The asynchronous event returns a promise, that I use the ,to update each of the items with the 2 values retuned by the asynchronous event. Each item is then saved back to the server, which is where my issue is occurring. When I debug this, the Function.createDelegate(this, this.success) has an udefined argument (b), that blows up on b.apply(). This is definitely not my strong suit in javascript. Can somebody help? See Code below:
Note - See //*Save Comment in Asychronous Function section for line which is causing issues.
HTML Button Calls Function
function UpdateSegmentSubsegment()
{
//1.) Query items where segment & sub-segment blank returnin array of items *
//2.) Loop through retuned items *
//3.) Get employee id *
//4.) Call Web Service and return segment & subsegment for employee id
//5.) Update item with segment & subsegment + Save
//6.)Loop
//Query Information Variables
var listname='ERD - XXXXX';
var caml='<View Scope="Recursive"><Query><Where><And>' +
'<IsNull><FieldRef Name="Employee_x0020_Business_x0020_Se" /></IsNull>' +
'<IsNull><FieldRef Name="Employee_x0020_Business_x0020_Su" /></IsNull>' +
'</And></Where></Query></View>';
//Function Variables
var itemcount=0;
var context = new SP.ClientContext.get_current();
QueryListItems(listname,caml,context).then(function(items){
//Get item count returned from promise
itemcount=items.get_count();
window.status="Preparing to Process"+itemcount.toString()+" items..."
//Prepare Looping object
var listitemenumerator=items.getEnumerator();
//Loop through each List Item
while (listitemenumerator.moveNext()) {
//Get Employee ID from list item collection
var listitem = listitemenumerator.get_current();
var employeeid=listitem.get_item("EmpUseAcct");
//Check for invalid item value
if(employeeid!="#Value!"){
//Ansychronous Function Call
QueryHRInformation(employeeid,listitem,context);
}
else
{
//Log CA Skip
window.status="Skiping CA Number "+listitem.get_item("Title").toString();
}
};
});
}
Query Function
//Query Promise
function QueryListItems(listname, CAMLQ,clientContext)
{
//Defererred Object
var deferred = new $.Deferred();
//Sharepoint Object Model
//Get List
var list = clientContext.get_web().get_lists().getByTitle(listname);
//CAML Query
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml(CAMLQ);
var items = list.getItems(camlQuery);
//Get Items
clientContext.load(items);
clientContext.executeQueryAsync(
Function.createDelegate(this,
function () { deferred.resolve(items); }),
Function.createDelegate(this,
function (sender, args) { deferred.reject(sender, args); }));
return deferred.promise();
}
Asychronous Function
//Asnchronous Function Call
function QueryHRInformation(employeeid,listitem,clientContext){
//Web Service Variables
var curequestorID="XXXXXX";
var wsserviceID="someweb-serviceid";
var wsservicePassword="somepassword";
var appIdentifier="someid";
var wsserviceName="SomeDetails";
//Debugging Variable to check async list item object
var title;
//Asynchronous Call
XXX.ERD.BizTalk.XX.getInstance().getInfo(employeeid,curequestorID, wsserviceID, wsservicePassword, appIdentifier, wsserviceName).then(function(empResult){
//Debugging Check
title=listitem.get_item("Title");
//Set list item values from web service object return (empResult)
listitem.set_item("Employee Business Segment",empResult.BusSegment);
listitem.set_item("Employee Business Sub Segment",empResult.SubSegment);
//Update list item values
listitem.update();
//*Save Item
clientContext.executeQueryAsync(Function.createDelegate(this, this.success), Function.createDelegate(this, this.failed));**
});
}
Upvotes: 0
Views: 735
Reputation: 21
Well I never leave my questions unanswered so others in the development community may benefit from my questions. Too many posts go unanswered, or just end after a solution is reached.
Yes, I figured it to be scoping issue a few weeks back, and solved my own issue. I wrapped them into functions passing along the values. When it is sent to the stack, it will not lose the scope of the values from the previous asynchronous call.
Inside the first function that makes an asynchrounous I pass the values and call this function:
SaveItem(listitem, clientContext, businesssegment,subsegment);
Here is the complete code:
function UpdateSegmentSubsegment()
{
//Prompt for Batching Note: Leave it blank to do all.
var camlrowlimit=prompt("Please enter the batch query","");
var camlbatch;
//Check Batch Input
if(camlrowlimit!=null)
{
//Set Dynamic RowLimit Variable
if(camlrowlimit=="")
{
camlbatch="";
}
else
{
camlbatch="<RowLimit>"+camlrowlimit+"</RowLimit>";
}
//Query Information Variables
var listname='ERD - XXXXX';
var caml='<View Scope="Recursive"><Query><Where><And>' +
'<IsNull><FieldRef Name="Employee_x0020_Business_x0020_Se" /></IsNull>' +
'<IsNull><FieldRef Name="Employee_x0020_Business_x0020_Su" /></IsNull>' +
'</And></Where></Query>'+camlbatch+'</View>';
//Function Variables
var itemcount=0;
var context = new SP.ClientContext.get_current();
QueryListItems(listname,caml,context).then(function(items){
//Get item count returned from promise
itemcount=items.get_count();
window.status="Preparing to Process "+itemcount.toString()+" items..."
//Prepare Looping object
var listitemenumerator=items.getEnumerator();
//Loop through each List Item
while (listitemenumerator.moveNext()) {
//Get Employee ID from list item collection
var listitem = listitemenumerator.get_current();
var employeeid=listitem.get_item("EmpUseAcct");
//Check for invalid item value
if(employeeid!="#Value!"){
//Ansychronous Function Call
QueryHRInformation(employeeid,listitem,context);
}
else
{
//Log CA Skip
console.log("Skiping CA Number "+listitem.get_item("CorrectiveActionNumber"));
}
};
});
}
}
//Query Promise
function QueryListItems(listname, CAMLQ,clientContext)
{
//Defererred Object
var deferred = new $.Deferred();
//Sharepoint Object Model
//Get List
var list = clientContext.get_web().get_lists().getByTitle(listname);
//CAML Query
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml(CAMLQ);
var items = list.getItems(camlQuery);
//Get Items
clientContext.load(items);
clientContext.executeQueryAsync(
Function.createDelegate(this,
function () { deferred.resolve(items); }),
Function.createDelegate(this,
function (sender, args) { deferred.reject(sender, args); }));
return deferred.promise();
}
//Asnchronous Function Call
function QueryHRInformation(employeeid,listitem,clientContext){
//Web Service Variables
var curequestorID="XXXXXX";
var wsserviceID="XXXXXX";
var wsservicePassword="XXXXXX";
var appIdentifier="XXXXXX";
var wsserviceName="XXXXXXX";
//Debugging Variable to check async list item object
//var title;
//Asynchronous Call
XXX.ERD.BizTalk.XX.getInstance().getInfo(employeeid,curequestorID, wsserviceID, wsservicePassword, appIdentifier, wsserviceName).then(function(empResult){
//Empresult.status
var businesssegment=empResult.BusSegment;
var subsegment= empResult.SubSegment;
SaveItem(listitem, clientContext, businesssegment,subsegment);
//*Save Item
//clientContext.executeQueryAsync(Function.createDelegate(this, this.success), Function.createDelegate(this, this.failed));
})
.fail(function(xhr, status, msg){
console.log(msg);
});
}
function SaveItem(item,ctx,bsg,ssg)
{
var refno;
//Debugging Check
refno=item.get_item("CorrectiveActionNumber");
//Set Fields
item.set_item("Employee_x0020_Business_x0020_Se",bsg);
item.set_item("Employee_x0020_Business_x0020_Su",ssg);
//Update list item values
item.update();
//ctx.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded),Function.createDelegate(this, this.onQueryFailed));
ctx.executeQueryAsync(Function.createDelegate(this,function(){ onQuerySucceeded(refno);}),Function.createDelegate(this, this.onQueryFailed));
}
function onQuerySucceeded(result, args) {
console.log('Saved CA Number'+result);
}
function onQueryFailed(sender, args) {
console.log('Request failed. ' + args.get_message()+'\n' + args.get_stackTrace());
}
Upvotes: 1
Reputation:
This should really be a comment but since do not have enough 'reputation'...
Anyway, to check whether it is a scoping issue, replace the issue line with this:
clientContext.executeQueryAsync(function(){console.log("Success"},function(){console.log("failed"})
If this resolves the issue then it was some sort of scoping issue.
Also, see this link for the correct syntax for updating item (i.e try to declare client context etc again when updating): https://learn.microsoft.com/en-us/sharepoint/dev/sp-add-ins/complete-basic-operations-using-javascript-library-code-in-sharepoint#create-update-and-delete-list-items
Finally, I recommend using this library: https://aymkdn.github.io/SharepointPlus/
Upvotes: 0