Retrieve a list of variable for a RITM

Originally asked by Alexander Lukashov on 25 February 2021 (original question)


Hi

I’m kinda struggling to get an array from sc_item_option_mtom table since it looks like nodeHelper doesn’t return an array but a fist item in the list

E.g consider the following code

if (entity.tableName.toString().equalsIgnoreCase('sc_task')) {


    Wrappers.MapWrapper variables = nodeHelper.getReference('sc_item_option_mtom', 'request_item', entity.request_item.display_value)
}

Now if you try to execute variables.entrySet().forEach you won’t be able to get all the variables, only the first one and forEach will simply allow you to iterate over properties in that first variable only

How do I get all variables for a given request item ID?

Thanks in advance


Answer by Francis Martens (Exalate) on 28 February 2021

Alex Fernandez

I had some time to dive into this one, and most of the time was spent on understanding how ServiceNow is handling this data.

Assume you want to transfer the variables of a Request Item to Jira

First step is to collect the variables from the request item, and then format it into the description (or do whatever is appropriate)

To collect the variables, check out in the Retrieve Catalog Variables snippet, the function ‘buildVariablesMap’ which will iterate over all the options related to the requestItem, and retrieve both the question and the associated answer.

This can be added to the replica by a statement like

replica.variables = buildVariablesMap(entity.key)

(The retrieve catalog variables snippet has an example outgoing sync)

Exalate will transport this list to the other side (in this case Jira)

The code to build the table as shown in the screenshot is pretty straightforward, leaning on the wiki rendering function of the description field.

Build a table

/*
** build a table from the variables
*/

String result = "\n||Question||Value||\n"
replica.variables?.each {
    result += "|${it.key}|${it.value}|\n"
}

issue.description  = result

Given that the variables are a map, you can use it in many different ways

Next up is - how to write the variables …


Comments:

Francis Martens (Exalate) commented on 28 February 2021

Added an ‘UpdateVariables.groovy’ logic which allows to update the variables.

The method takes a request item number and a map.
It checks for each option associated to the request item, if the question is in the map (key), and if the value of the option is different. In case of a difference - it will update the request item option.

if (entity.tableName == "sc_req_item") {
    def varMap = ["What was the original phone number?":"1234567" ]
    
    updateVariables(entity.key, varMap)
    
}
Alexander Lukashov commented on 01 March 2021

Hi Francis

Many thanks, that’s exactly I was looking for

Just few things I want to mention

  • For sc_item_option which contains a reference to a user in a value attribute you still need to implement a custom logic to resolve this reference otherwise you’ll get a guid instead of display name
  • My tests showed that retrial of variables is kinda slow so I changed the method to have only one API call using tables join in ServiceNow table API. Maybe somebody will find it useful
Map buildVariablesMap(String entityNumber) {
    def Map result = [:]


    // lookup all options associated to this number

    def optionList = httpClient.get("/api/now/table/sc_item_option?sysparm_query=^!JOINsc_item_option.sys_id=sc_item_option_mtom.sc_item_option!^JOINsc_item_option_mtom.request_item=sc_req_item.sys_id!sys_id=e6f7defedb5e2010073c6693ca961940&sysparm_display_value=true&sysparam_fields=item_option_new,value")
    if (!optionList || !optionList.result) return null  // ignore if there are no results


    // For each of the options, lookup corresponding question and add to the result map
    optionList.result.each {
        if(it.value.toString().isEmpty()) return

        result.put(it.item_option_new.display_value, it.value)
    }

    return result

}
Francis Martens (Exalate) commented on 02 March 2021

Nice - I was not aware of that capability. Need to learn about join

Alexander Lukashov commented on 02 March 2021

Yeah, I wasn’t aware about that as well (I’m completely new to ServiceNow), found it on some of the servicenow forums by accident

Karen Jennings commented on 05 November 2021

I kept running into a problem using outgoing example from here: Retrieve Catalog Variables.

It was trying to pull ALL of the variables from all of the forms. By tweaking the ServiceNow outgoing script a little, and building the table in Jira to see the values, I was able to get it to pull ONLY those variables on the form submitted.

Once I narrowed it down, it was easy to look at both the table and the payload to figure out the syntax to map those variables to specific field in Jira.

Here is what I used for the ServiceNow outgoing sync:

Map buildVariablesMap(String request_item_number) {
def Map result = [:]

// lookup all options associated to this number  
  
def optionList \= httpClient.get("/api/now/table/sc\_item\_option\_mtom?sysparm\_query\=request\_item.numberSTARTSWITH${request\_item\_number}")  
if (!optionList \|\| !optionList.result) return null // ignore if there are no results
Ariel Aguilar commented on 05 November 2021

Hi Karen have you tried?:

Map buildVariablesMap(String requestItemNumber) {
    def Map result = [:]
 
   
    // lookup all options associated to this number
   
    def optionList = httpClient.get("/api/now/table/sc_item_option_mtom?sysparm_query=request_item.numberSTARTSWITH${requestItemNumber}")
    if (!optionList || !optionList.result) return null // ignore if there are no results

Kind regards,

Ariel

Francis Martens (Exalate) commented on 05 January 2022

For new readers looking for this solution

Make sure that the query which retrieves the variables is properly limiting the number of entries.
One of our customers used a query which downloaded the whole table …

Alejandro Fernandez commented on 11 January 2023

Hi,

Is there any way to update the variables in ServiceNow usign values from Jira?

I’ve been able to update fields on ChangeRequests but it looks that the same fields are variables in Service Requests and I’m not able to update them.

I’ve seen this code Francis Martens (Exalate) put on this thread but I’m not being capable of making it work:

if (entity.tableName == "sc_req_item") {
    def varMap = ["What was the original phone number?":"1234567" ]
     
    updateVariables(entity.key, varMap)
     
}

Can you help me?

Thanks in advance.

Regards.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.