The CreatorCon Call for Content is officially open! Get started here.

How to iterate through an array and run rest message for each array item

triciav
Kilo Sage

I have a run script in my workflow that is calling a script include to run a rest message

My run script is as such:

var array = (current.variables.sam_accountname.toString()).split(",");
for (var i = 0; i < array.length; i++){
var samAccount = array[i];

gs.log("This is the SamAccounts "+array[i]);

This is the SamAccounts ttest3delete
This is the SamAccounts ttest4delete

var obj = new OffboardDisableAD();//name of script include

var returnedData = obj.disableAD(samAccount);//function call *This is were I need to loop through and pass each samAccount to the function so it iterates and runs for each array item

var json = new global.JSON();

//var returnedData = obj.DisabledAccounts('disabledAccountsData');
var obj2 = JSON.parse(returnedData);

workflow.scratchpad.statusad = obj2.status;
workflow.scratchpad.msgad = obj2.data;
}

This is the code in my script include: 
How do I get this to run for each array samaccount

gs.log("THIS IS THE Script include samAccounts "+samAccount[i]);

THIS IS the ScriptInclude users ttest3delete,ttest4delete


var request = new sn_ws.RESTMessageV2();
//devca19
//intranetappca02
request.setEndpoint('https://EP/sshadmin/api/Home/ServiceNowCommandGet?command=' + this.command + '&userName=' + this.user + '&passWord=' + this.password + '&userNameForCommand=' + samAccount);

19 REPLIES 19

It is strange that only making 1 API call works but making multiple calls doesn't - If I'm honest the endpoint that you are calling should not care how often it is called.

Implicit waits are something you want to avoid because you can't guarantee that the API will always respond within that time.

Also don't think it is possible to use promises in ServiceNow server-side code because the script engine runs ECMAScript 5.

One option might be to look into creating "Script Actions" and the "Event Queue". In this case you would create an event with and pass it the specific samAccount. The script action would then read the param and make the call to the script include.

https://docs.servicenow.com/bundle/newyork-platform-administration/page/administer/platform-events/r...

https://community.servicenow.com/community?id=community_question&sys_id=1a074be5db1cdbc01dcaf3231f96...

 

I think it is unrelated but you are overwriting the workflow scratchpad variables each time you receive a response so your scratchpad variables will end up storing the last value that was returned. Are you going to need the responses of each one kept?

var obj2 = JSON.parse(returnedData);

workflow.scratchpad.statusad = obj2.status;
workflow.scratchpad.msgad = obj2.data;

Hi Dan, 

Yes I am actually going to need the response for each return

ugh this is getting complicated 😞

I will look at the Script actions and events which might be the solution to doing this that you posted.

How would I go about getting all the returned results to scratchpad?

Thank you so much for helping me on this

 

Dan,

My samAccounts are an array could be 1 or multiple

You mention 

In this case you would create an event with and pass it the specific samAccount. 

If its an array how do I pass that a sspecific?

 

Storing all of the responses in a single workflow scratchpad variable.

var array = (current.variables.sam_accountname.toString()).split(",");

// New variables used to store the API response objects
var apiResponseStatus = [];
var apiResponseData = [];

// Loop through the array of accounts
for (var i = 0; i < array.length; i++){
    var samAccount = array[i];
    gs.log("Processing SAM Account: " + array[i]);

    var returnedData = new OffboardDisableAD().disableAD(samAccount.toString());
    var obj2 = JSON.parse(returnedData);
    
    apiResponseStatus.push(obj2.status);
    apiResponseData.push(obj2.data);
}

// Set the scratchpad outside of the for loop
workflow.scratchpad.statusad = apiResponseStatus;
workflow.scratchpad.msgad = apiResponseData;
In this case you would create an event with and pass it the specific samAccount. 

Inside of the for loop in the code example above you would create an event and a bit like a function call you would include "samAccount" in it. For example:

var array = (current.variables.sam_accountname.toString()).split(",");

// Loop through the array of accounts
for (var i = 0; i < array.length; i++){
    var samAccount = array[i];

    gs.eventQueue('your.event.name', current, samAccount);
}

Thanks, Dan

 

MrMuhammad
Giga Sage

Hi Triciav, 

 

  • Have you tried with some static values and is it working as expected?
  • Have you tried making rest call through Postman, how does it goes? 

 

Thanks & Regards,

Sharjeel 

 

 

 

Regards,
Muhammad