Getting variable sys ids instead of values

GBS
Tera Contributor

I'm using the script below to include the catalogue variables in the Word document after submitting the request. However, the issue is that the Word file is getting updated with the sys IDs of the variable values. The variable types are Single line text and Select box

 

Script Include:

var ServiceNow = Class.create();
ServiceNow.prototype = {
    initialize: function() {},

    ritmDetails: function(ritmSysId) {
        try {
            var ritm = new GlideRecord('sc_req_item');
            if (!ritm.get(ritmSysId)) {
                gs.info('RITM not found' + ritmSysId);
                return;
            }
            var number = ritm.number;
            var name = ritm.cat_item.name;
            var variables = this._getVariables(ritmSysId);

            var html = "<html><body>";
            html += "<h2 style='color:#2F5496;'>Requested Item Details</h2>";
            html += "<p><b>RITM:</b> " + number + "<br>";
            html += "<b>Catalog Item:</b> " + name + "</p>";
            html += "<h3 style='color:#1F4E79;'>Variables</h3>";

            for (var i = 0; i < variables.length; i++) {
                html += "<p><b>" + variables[i].name + ":</b> " + variables[i].value + "</p>";
            }

            html += "</body></html>";

            var output = number + "_Details.doc";

            var attachment = new GlideSysAttachment();
            attachment.write(ritm, output, "application/msword", html);

            gs.info("Word document generated and attached for " + number);
        } catch (ex) {
            gs.info("Error generating word document: " + ex);
        }
    },

    _getVariables: function(ritmSysId) {
        var vars = [];
        var variables = new GlideRecord('sc_item_option_mtom');
        variables.addQuery('request_item', ritmSysId);
        variables.query();
        while (variables.next()) {
            var varRec = variables.sc_item_option.item_option_new;
            var variableName = varRec.getDisplayValue('question_text') || varRec.getDisplayValue('name');
            var variableValue = variables.sc_item_option.getDisplayValue('value') || variables.sc_item_option.value;

            vars.push({
                name: variableName,
                value: variableValue
            });
        }
        return vars;
    },

    type: 'ServiceNow'
};
1 ACCEPTED SOLUTION

Ankur Bawiskar
Tera Patron
Tera Patron

@GBS 

don't use sc_item_option_mtom table.

Instead use this logic for getting variables

 _getVariables: function(ritmSysId) {
        var vars = [];
        var set = new GlideappVariablePoolQuestionSet();
        set.setRequestID(ritmSysId);
        set.load();
        var vs = set.getFlatQuestions();
        for (var i = 0; i < vs.size(); i++) {
            var variableLabel = vs.get(i).getLabel();
            var variableValue = vs.get(i).getDisplayValue();
            vars.push({
                name: variableLabel,
                value: variableValue
            });
        }
        return vars;
    },

💡 If my response helped, please mark it as correct and close the thread 🔒— this helps future readers find the solution faster! 🙏

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

View solution in original post

3 REPLIES 3

harishk07
Tera Expert

Hi @GBS 

 

You’re pulling from sc_item_option_mtom → sc_item_option.value, which always stores the raw value. For reference and select box variables you must resolve the display text yourself.

In your _getVariables() replace the value line with logic that:

  1. If the variable is reference / lookup select box / list collector → fetch the record from the reference table and use its display value.
  2. If the variable is a select box (non-reference) → look up the label in question_choice for that question/value.
  3. Else → use the raw text for Single line texts.

Here’s a "rough" (non-tested) replacement for _getVariables:

 

_getVariables: function(ritmSysId) {
  var out = [];
  var mtom = new GlideRecord('sc_item_option_mtom');
  mtom.addQuery('request_item', ritmSysId);
  mtom.query();
  while (mtom.next()) {
    var q = mtom.sc_item_option.item_option_new; // variable definition (item_option_new)
    var name = q.getDisplayValue('question_text') || q.getDisplayValue('name');
    var raw = mtom.sc_item_option.value + '';
    var disp = raw;

    var typeName = q.getDisplayValue('type');        // e.g., "Reference", "Select Box", "List Collector"
    var refTable = q.getValue('reference');          // set for reference types

    // Reference / Lookup Select Box / List Collector → resolve display from ref table
    if (refTable) {
      var ref = new GlideRecord(refTable);
      if (ref.get(raw)) disp = ref.getDisplayValue();
    }
    // Plain Select Box (choices defined on the variable) → resolve label from question_choice
    else if (typeName === 'Select Box') {
      var ch = new GlideRecord('question_choice');
      ch.addQuery('question', q.getUniqueValue());
      ch.addQuery('value', raw);
      ch.query();
      if (ch.next()) disp = ch.getValue('text') || ch.getValue('label') || raw;
    }
    // else: Single Line Text / etc. → raw is already the display

    out.push({ name: name, value: disp });
  }
  return out;
}

 

getDisplayValue('value') on sc_item_option won’t translate sys_ids for reference/select variables. it’s just a string field. Resolving via the reference table or question_choice gives you the human-readable label you expect.

 

If you still see sys_ids:

Confirm the variable’s type (q.getDisplayValue('type')) and reference table (q.reference) are set as expected.

For list collectors, raw is a comma-separated list of sys_ids; split and map each to its display value using the same reference-table lookup loop.

 

Please mark as correct and helpful if it solved your query.

 

Best Regards,
Harish

✔️ Kindly mark as Helpful / Accept Solution if this answered your question

debendudas
Mega Sage
Mega Sage

Hi @GBS ,

In your _getVariables method, you're retrieving variable values using:

var variableValue = variables.sc_item_option.getDisplayValue("value") || variables.sc_item_option.value;

 

Since you're dot-walking through multiple records, getDisplayValue in this case returns the display value of the sc_item_option record itself, which is typically the sys_id for this table.

 

To correctly retrieve the display value of the actual variable, you need to explicitly access the 'value' field and then call getDisplayValue() on it, like this:

var variableValue =
variables.sc_item_option.value.getDisplayValue() ||
variables.sc_item_option.value;

 

So, only 1 line change will resolve ✔️ your issue!

 

If this solution helps you then, mark it as accepted solution ‌‌✔️ and give thumbs up 👍

Ankur Bawiskar
Tera Patron
Tera Patron

@GBS 

don't use sc_item_option_mtom table.

Instead use this logic for getting variables

 _getVariables: function(ritmSysId) {
        var vars = [];
        var set = new GlideappVariablePoolQuestionSet();
        set.setRequestID(ritmSysId);
        set.load();
        var vs = set.getFlatQuestions();
        for (var i = 0; i < vs.size(); i++) {
            var variableLabel = vs.get(i).getLabel();
            var variableValue = vs.get(i).getDisplayValue();
            vars.push({
                name: variableLabel,
                value: variableValue
            });
        }
        return vars;
    },

💡 If my response helped, please mark it as correct and close the thread 🔒— this helps future readers find the solution faster! 🙏

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader