I've seen a lot of info on the above question but none of it has answered what I'm looking for, so far. I'm trying to retrieve list items that have a great number of lookup fields. I've had success getting to some of the lookup values but not others and I can't figure out why. Also, it would appear that 'null' items are not accepted in the returned data? If the lookup field does not contain a value, it throws an error? Is this correct? Below is my code. The other issue (the big issue mentioned in my title) is that lookup values where I'm trying to pull in something, other than ID or Title, throws an error: reference not found or initialized. In this instance my lookup field is referencing a calc column returned as a single line of text. So my lookup field is Course1Date/DateRange, where DateRange represents the fieldname of the calc column. Error: "The property or field has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested."
function getLookupValues(){
var clientContext = SP.ClientContext.get_current();
var list = clientContext.get_web().get_lists().getByTitle('Lookup');
var caml = new SP.CamlQuery();
caml.set_viewXml('<View><Query><Where><Geq>' +
'<FieldRef Name=\'ID\'/><Value Type=\'Number\'>82</Value>' +
'</Geq></Where></Query><RowLimit>10</RowLimit></View>');
var returnedItems = list.getItems(caml);
clientContext.load(returnedItems);
clientContext.executeQueryAsync(success, failure);
}
function success(){
var listiteminfo='';
var enumerator = returnedItems.getEnumerator();
while(enumerator.moveNext())
{
var listItem = enumerator.get_current();
if(listItem.get_item('Course1')) {
var course1 = listItem.get_item('Course1').get_lookupValue();
}
if(listItem.get_item('Course2')) {
var course2 = listItem.get_item('Course2').get_lookupValue();
}
if(listItem.get_item('Course1Date')) {
var course1Date = listItem.get_item('Course1Date').get_lookupValue();
} //throws error for this lookup field
listiteminfo += '\nCourse1: '+course1+'\nCourse2: '+course2+'\nCourse1Date: '+course1Date;
}
alert(listiteminfo);
}
function failure(){
alert("Failed");
}
You have initialize the fields to get Lookup Values. Have to load the ListItem in context. And if there is a null value in lookup field, get.lookupValue() will throw an exception. So check the field value is not null before getting lookup value. Please try my workaround below and let me know if it works.
function getLookupValues() {
var clientContext = SP.ClientContext.get_current();
var list = clientContext.get_web().get_lists().getByTitle('Lookup');
targetListItem = list.getItemById(82);
clientContext.load(targetListItem, 'Title');
clientContext.load(targetListItem, 'Course1');
clientContext.load(targetListItem, 'Course1Date');
clientContext.load(targetListItem, 'Course2');
clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}
function onQuerySucceeded() {
var resultData = "";
resultData += targetListItem.get_item('Title');
if (targetListItem.get_item('Course1') != null)
resultData += targetListItem.get_item('Course1').get_lookupValue();
if (targetListItem.get_item('Course1Date') != null)
resultData += targetListItem.get_item('Course1Date').get_lookupValue();
if (targetListItem.get_item('Course2') != null)
resultData += targetListItem.get_item('Course2').get_lookupValue();
alert(resultData);
}
function onQueryFailed(sender, args) {
alert('Request failed. \nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
}
Related
I retrieve values from a SharePoint list and put them in an array itemprices.
Using console.log("Price of list item at is:" + itemprices[oListItem.id]); will print out the values of the array, but using console.log("itemprices 5: " + itemprices[5]); tells me that they are undefined:
This is the code I used:
var itemprices = [];
// Gets values from Catalogue list; but they can't be used in the Position list because of different formats
function retrieveListItems() {
var clientContext = new SP.ClientContext.get_current();
catalogueList = clientContext.get_web().get_lists().getByTitle('Catalog');
var camlQuery = new SP.CamlQuery(); // initiate the query object
camlQuery.set_viewXml('<View><Query><Where><In><FieldRef Name=\'ID\'/><Values><Value Type=\'Number\'>5</Value><Value Type=\'Number\'>6</Value><Value Type=\'Number\'>7</Value></Values></In></Where></Query></View>');
itemColl = catalogueList.getItems(camlQuery);
// returns the item collection based on the query
context.load(itemColl);
context.executeQueryAsync(retrieveListItemsSuccess, retrieveListItemsFail);
}
function retrieveListItemsSuccess() {
var listItemEnumerator = itemColl.getEnumerator();
while (listItemEnumerator.moveNext()) {
var oListItem = listItemEnumerator.get_current();
itemprices[oListItem.id] = oListItem.get_item('Preis');
console.log("itemprices 5: " + itemprices[5]);
console.log("itemprices 6: " + itemprices[6]);
console.log("itemprices 7: " + itemprices[7]);
console.log("Price of list item at is:" + itemprices[oListItem.id]);
}
}
// This function is executed if the above call fails
function retrieveListItemsFail(sender, args) {
alert('Failed to get list items. Error:' + args.get_message());
}
I don't know if this is a JavaScript issue or a SharePoint issue. What am I doing wrong?
Firstly, please use the right ClientContext object, in the code snippet above, it should be clientContext rather than context and if you want to populate field values into an array, try to use array.push, here is the modified code snippet for your reference:
<script type="text/javascript">
ExecuteOrDelayUntilScriptLoaded(retrieveListItems, 'sp.js');
var itemprices = [];
// Gets values from Catalogue list; but they can't be used in the Position list because of different formats
function retrieveListItems() {
var clientContext = new SP.ClientContext.get_current();
catalogueList = clientContext.get_web().get_lists().getByTitle('Companies');
var camlQuery = new SP.CamlQuery(); // initiate the query object
camlQuery.set_viewXml('<View><Query><Where><In><FieldRef Name=\'ID\'/><Values><Value Type=\'Number\'>5</Value><Value Type=\'Number\'>6</Value><Value Type=\'Number\'>7</Value></Values></In></Where></Query></View>');
itemColl = catalogueList.getItems(camlQuery);
// returns the item collection based on the query
clientContext.load(itemColl);
clientContext.executeQueryAsync(retrieveListItemsSuccess, retrieveListItemsFail);
}
function retrieveListItemsSuccess() {
var listItemEnumerator = itemColl.getEnumerator();
while (listItemEnumerator.moveNext()) {
var oListItem = listItemEnumerator.get_current();
itemprices.push(oListItem.get_item('Title'));
}
console.log(itemprices);
}
// This function is executed if the above call fails
function retrieveListItemsFail(sender, args) {
alert('Failed to get list items. Error:' + args.get_message());
}
</script>
This is my list data:
This is the array from Console:
You can just use this function:
itemprices.map(itemPrice => console.log(itemPrice))
The following code works to get the a list GUID by Title. What I cannot figure out is how to get the code to return that value so it can be assigned to a variable.
I am fairly new to JavaScript so the nuances trouble me. I understand most of what is going on in the code. I added the alert() in the success function however, I cannot figure out where to put the return statement to get the GUID value back.
var list;
function getListId(listTitle) {
var context = new SP.ClientContext.get_current();
var web = context.get_web();
list = web.get_lists().getByTitle(listTitle);
context.load(list, 'Id');
context.executeQueryAsync(Function.createDelegate(this,success), Function.createDelegate(this,error));
}
function success() {
var listId = list.get_id();
// console.log(listId);
alert(listId);
return listId;
}
function error(sender, args) {
alert('Request failed. ' + args.get_message() +
'\n' + args.get_stackTrace());
}
This is asynchronous, so you can't "return" it in the sense you seem to be talking about. What you would normally do, however, is execute the code you need to execute for handling the listId from within your success function:
var list;
function getListId(listTitle) {
var context = new SP.ClientContext.get_current();
var web = context.get_web();
list = web.get_lists().getByTitle(listTitle);
context.load(list, 'Id');
context.executeQueryAsync(Function.createDelegate(this,success), Function.createDelegate(this,error));
}
function success() {
var listId = list.get_id();
// console.log(listId);
alert(listId);
handleListId(listId);
}
function error(sender, args) {
alert('Request failed. ' + args.get_message() +
'\n' + args.get_stackTrace());
}
function handleListId(listId) {
//DO STUFF WITH YOUR listId HERE...
}
I am fairly new to js and node.js but I have managed to get the calls going to the API and getting the necessary information. However when I was attempting to continue to raise the batter id to get the next information available. I have successfully gotten the undefined error check to work as well. But I was unable to loop through because I was trying to perform something immediately on an async function. I am now trying to make the entire function async with a 2 second delay after each run, but it is returning the following error (i'm assuming because something is undefined)
**Note: When I just get the value for i=4 and p=1 the value does exist in the API data. However it gives this error when I attempt to start with those values using this code.
error:
Unexpected token u in JSON at position 0
this is my code:
request('API Info redacted',
setTimeout (function (err, response, body) {
//do stuff below
//to get the first play of the game, set i=1 and p=0
var i = 4;
var p = 1;
// ************
var boolIn = 1;
// parse the body as JSON
var parsedBody = JSON.parse(body);
var apiResults = parsedBody.apiResults;
if( typeof(apiResults[0].league.season.eventType[0].events[0].pbp[i].pbpDetails[p]) == 'undefined') {
//sets the variables to the first batter of the next inning
p=0;
i = i+1;
}
//below pulls the apiResults from the body of the API request
var sportId = apiResults.sportId;
var hitName = apiResults[0].league.season.eventType[0].events[0].pbp[i].pbpDetails[p].name;
var fname = apiResults[0].league.season.eventType[0].events[0].pbp[i].pbpDetails[p].batter.firstName;
var lname = apiResults[0].league.season.eventType[0].events[0].pbp[i].pbpDetails[p].batter.lastName;
var outsB = apiResults[0].league.season.eventType[0].events[0].pbp[i].pbpDetails[p].outs.before;
var outsA = apiResults[0].league.season.eventType[0].events[0].pbp[i].pbpDetails[p].outs.after;
var rbis = apiResults[0].league.season.eventType[0].events[0].pbp[i].pbpDetails[p].runsBattedIn;
var outDifference = (outsA - outsB);
var hitB = apiResults[0].league.season.eventType[0].events[0].pbp[i].pbpDetails[p].baseSituation.beforeId;
var hitA = apiResults[0].league.season.eventType[0].events[0].pbp[i].pbpDetails[p].baseSituation.afterId;
var baseDifference = (hitA - hitB);
//prints the details pulled above
res.json("First Name: " + fname + ", Last Name: " + lname + ", Hit name: " + hitName + ", Outs on the play: " + outDifference + ", Rbi's: " + rbis +
", Base Sit: " + baseDifference);
//increases the batter call
p = p+1;
//below ends the setTimeout
}, 2000));
//ended request
});
setTimeout will not pass arguments to the function it calls, so body is undefined. When you pass that to JSON.parse, it will be converted to the string "undefined", which isn't a valid JSON text.
Nowhere is your code do you show any JSON coming into your program (or embedded into it). You need to have some JSON to parse before you try to parse it.
Hi I'm trying to create a rest response using post method, I want to dynamically pass the variables instead of hard coding,But where i fail is,when I'm trying to to send an array as a parameter to the Rest web service using post method(example array ["CN=XXX_XX,OU=XXXXX,OU=1_XXXX XXXXity Groups,DC=XXXX,DC=local"]) and I know that there is a better way to do that Please find my code sample.This is the method that gives me a appropriate result.
First Method:(Works)
`
try {
var r = new sn_ws.RESTMessageV2('SailPoint_IdM', 'post');
var txt = "{\r\n\t\"workflowArgs\":\r\n\t{\r\n\t\"identityName\":\"SiamR\",\r\n\t\"appName\":\"Active Directory\",\r\n\t\"listEntitlements\":[\"CN=ER_CxxxK,OU=xxxxx,OU=1_xxxxxx Security xxx,DC=xxxx,DC=local\"],\r\n\t\"operation\":\"Add\",\r\n\t\"ticketNumber\":\"RITM1234567\"\r\n\t}\r\n}";
r.setRequestBody(txt);
var response = r.execute();
var ResponseBody = response.getBody();
var HTTPCode = response.getStatusCode();
gs.log(ResponseBody);
gs.log(HTTPCode);
} catch (ex) {
var message = ex.getMessage();
}
output:
Script: {"attributes":{"requestResult":{"status":"Success"}},"complete":false,"errors":null,"failure":false,"metaData":null,"requestID":"2c988d8c5bd47cf7015bebfb64cf01e6","retry":false,"retryWait":0,"status":null,"success":false,"warnings":null}
Script: 200
2n Method (Does not Work):
try {
var r = new sn_ws.RESTMessageV2('SailPoint_IdM', 'post');
r.setStringParameter('"listEntitlements"', '["CN=Exxx_xxxK,OU=xxxxion,OU=1_xxxxx Security xxxx,DC=xxx,DC=xxxx"]');
r.setStringParameter('"identityName"', '"SiarmR"');
r.setStringParameter('"appName"', '"Active Directory"');
r.setStringParameter('"ticketNumber"', '"RITM1234567"');
r.setStringParameter('operation', '"Add"');
//override authentication profile
//authentication type ='basic'/ 'oauth2'
//r.setAuthentication(authentication type, profile name);
var response = r.execute();
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
gs.log(responseBody );
}
catch(ex) {
var message = ex.getMessage();
}
output:
Script: {"attributes":{"requestResult":{"errors":["An unexpected error occurred: sailpoint.tools.GeneralException: The application script threw an exception: java.lang.NullPointerException: Null Pointer in Method Invocation BSF info: script at line: 0 column: columnNo"],"status":"FAIL","GroupStatus":null,"AppStatus":null}},"complete":false,"errors":["Status : failed\nAn unexpected error occurred: sailpoint.tools.GeneralException: The application script threw an exception: java.lang.NullPointerException: Null Pointer in Method Invocation BSF info: script at line: 0 column: columnNo\n"],"failure":false,"metaData":null,"requestID":null,"retry":false,"retryWait":0,"status":null,"success":false,"warnings":null}
Script: 200
Im facing issue with this parameter as im trying to pass this as aray paramenter '["CN=Exxx_xxxK,OU=xxxxion,OU=1_xxxxx Security xxxx,DC=xxx,DC=xxxx"]'
Please suggest a way to implement this and to pass all the variables dynamically if suggesting first method
Below is one of my function, to handle dynamic parameters in either appear in request endpoint (url), headers or body;
For eg: parameter p
var p = {abc: 'def'};
and outbuond rest settings:
rest url = https://xxxx.sss.com/api/showme?name=${abc}
rest headers name = custom-header; value = ${abc}
rest body = {name: "${abc}"}
so it will replace all ${abc} to 'def'
_.isNullOrEmpty - check is obj, string or array is null or empty;
_.loop - loop an obj or array, pass in function(nm/i, val) {}
_.isArray - to check if is array
_.str - convert anything to string
_.rpl - replace all string A to B
restParameters: function (restRequest, obj, endpoint) {
var _ = this;
if ((_.isNullOrEmpty(restRequest)) || (_.isNullOrEmpty(obj))) return;
if (_.isNullOrEmpty(endpoint)) endpoint = restRequest.getEndpoint();
var body = restRequest.getRequestBody();
var headers = restRequest.getRequestHeaders();
_.loop(obj, function(nm, val) {
if (_.isArray(val)) {
val = (_.isNullOrEmpty(val)) ? '[]' : JSON.stringify(val);
} else val = _.str(val);
//for my case my array pass in as string become: "[\"1\", \"2\"]"
//comment below if pass in as object
if (val.contains('"')) val = _.rpl(val, '"', '\\"');
restRequest.setStringParameterNoEscape(nm, val);
var sch = '${' + nm + '}';
endpoint = _.rpl(endpoint, sch, val);
body = _.rpl(body, sch, val);
_.loop(headers, function (hn, hv) {
headers[hn] = _.rpl(hv, sch, val);
});
}, true);
restRequest.setEndpoint(endpoint);
restRequest.setRequestBody(body);
_.loop(headers, function (hn, hv) { restRequest.setRequestHeader(hn, hv); });
}
Well i have created a function to return the picture url. See code below:
function loadAttachment(itemid) {
web = context.get_web();
attachmentFolder = web.getFolderByServerRelativeUrl("Lists/LijstMedewerkers/Attachments/" + itemid);
attachmentFiles = attachmentFolder.get_files();
//Load attachments
context.load(attachmentFiles);
context.executeQueryAsync(onLoaddAttachmentSuccess, onLoadAttachmentFail);
alert(picture);
return picture;
}
function onLoadAttachmentFail(sender, args) {
alert('Failed to get lists items. Error:' + args.get_message());
}
function onLoaddAttachmentSuccess(sender, args) {
// Enumerate and list the Asset Attachments if they exist
var attachementEnumerator = attachmentFiles.getEnumerator();
while (attachementEnumerator.moveNext()) {
var attachment = attachementEnumerator.get_current();
picture = attachment.get_serverRelativeUrl();
}
}
Well it's not returning the value of the picture. When i do an alert i see the value but with the return it's not working. even if i put the picture in the itemid.
Any idea what i'm doing wrong ?
Since SP.ClientContext.executeQueryAsync method is async:
SP.ClientContext.executeQueryAsync(succeededCallback, failedCallback)
succeededCallback is used for declaring function that contains the returned results.
When working with asynchronous API such as JSOM the following patterns are commonly used:
Using nested callbacks
Using the promises pattern
The below example demonstrates how to retrieve attachment files using callback approach:
function loadAttachments(listTitle, itemId,success,error) {
var context = new SP.ClientContext.get_current();
var web = context.get_web();
var list = web.get_lists().getByTitle(listTitle);
var listItem = list.getItemById(itemId);
var files = listItem.get_attachmentFiles();
context.load(files);
context.executeQueryAsync(function(){
success(files);
},
error);
}
Usage
Get first file attachment url
loadAttachments('Projects',3,
function(attachmentFiles){
if(attachmentFiles.get_count() > 0) {
var attachmentFile = attachmentFiles.getItemAtIndex(0);
var fileUrl = attachmentFile.get_serverRelativeUrl();
//...
}
},
function(sender,args){
console.log(args.get_message());
});