Populating ServiceNow Record Producer's Description Field with Only Answered Questions

Sysop
Tera Contributor

Hello,

 

I am currently working with a record producer that contains multiple questions, approximately 40 in total. Depending on the user's response to certain questions, other questions may be unhidden. Once submitted, the record producer creates a ticket in a custom table, 'u_mktg'.

 

I have a specific requirement to populate the 'description' field of this ticket with ONLY the questions and their corresponding answers that have been responded to by the user. Questions that do not have an answer should not be included in the description.

 

I created this script on the record producer but it didn't work

 

(function run() {
    var description = '';
    for (var key in producer.variables) {
        var variable = producer.variables[key];
        var answer = variable.getValue();
        if (answer) {
            var question = variable.getLabel();
            description += question + ': ' + answer + '\n';
        }
    }
    current.description = description;
})();

 

 

The logic behind the script being that the script loops through each variable in the producer, checks if the variable has a value, and if it does, it appends the question (label of the variable) and answer to the description. The 'description' field in the newly created record will be populated with these question-answer pairs.

The getValue() function will return an empty string if the variable has not been filled by the user, which will evaluate to false in the if condition, effectively filtering out unanswered questions.

 

Well, like I said, it didn't work.  I would appreciate some suggestions to either fix my script or on taking a different approach to the matter.  Thank you in advance.

2 REPLIES 2

svirkar420
Tera Expert

Hello @Sysop , Try the below script in the record producer's script field.

(function run() {
var description = '';
var variables = producer.variables.getElements(); // get all variables

for (var i = 0; i < variables.length; i++) {
var v = variables[i];
var answer = producer[v.getName()]; // get value of variable
if (answer) {
var question = v.getLabel(); // get the label (question text)
description += question + ': ' + answer + '\n';
}
}

current.description = description;
})();

 

PleaseMark this solution as accepted and helpful as it will be helpful for other users and readers as well.
Best Regards.

Saurabh V.

Astik Thombare
Tera Sage

Hi @Sysop ,

 

I have worked on a similar requirement earlier where I needed to update the Description of an HR Case with only the fields that were visible to the end user. For that I used the client-side API g_form.getEditableFields() to collect only visible variables and build a description string. The same approach works perfectly for your u_mktg record producer.

 

Why client-side is best here


The client knows exactly which variables were visible (conditions/UI policies) and what the user actually entered. g_form.getEditableFields() returns only visible/editable variables.

Building the description on the client just before submit guarantees you capture the UI state the user saw.

Server-side producer script objects may not expose labels/values the same way, and it’s harder to determine what the end user actually saw.

 

Setup (step-by-step)

 

1.On the Record Producer, create a hidden variable:

  • Type: String / Long Text / HTML (long text recommended if your description may be long).
  • Name: u_desc_collector (or any name you prefer).
  • Make sure it exists on the same Catalog Item/Record Producer as the other variables.
  • In the variable configuration set "Mapped to" (Mapped to field) = description on your target table (u_mktg).
    Optionally, if you prefer server-side mapping, skip the direct mapping and set current.description in the Record Producer script (example below).

2.Create a Catalog Client Script on the Record Producer:

  • Type: Catalog Client Script
  • UI Type: Desktop / Mobile / (Service Portal: see below)
  • Script: use the onSubmit script below.
// Catalog Client Script (onSubmit)
function onSubmit() {
  try {
    var description = '';
    var visibleVars = g_form.getEditableFields(); // only visible/editable variables
    for (var i = 0; i < visibleVars.length; i++) {
      var varName = visibleVars[i];

      // Skip the collector variable itself if its name appears in the list
      if (varName === 'u_desc_collector') continue;

      var value = g_form.getValue(varName);

      // Normalize value to string and trim
      if (value !== null && value !== undefined) {
        value = value.toString().trim();
      }

      if (value && value.length > 0) {
        var label = g_form.getLabelOf(varName) || varName;

        // Handle multi-selects or arrays: g_form.getValue returns CSV for multi-selects;
        // you can split and pretty-format if needed:
        // if (value.indexOf(',') !== -1) value = value.split(',').join(', ');

        // Optional: limit very long answers
        var safeValue = value;
        if (safeValue.length > 2000) safeValue = safeValue.substring(0, 2000) + '...';

        description += label + ': ' + safeValue + '\n\n';
      }
    }

    // Put the built description into the hidden variable that maps to description
    g_form.setValue('u_desc_collector', description);

  } catch (err) {
    // don't block submission if something goes wrong; log for debugging
    console.error('onSubmit description builder error: ', err);
  }

  return true; // allow submit
}

 

Notes:

  • g_form.getEditableFields() returns variables visible to the end user (honors UI policies/conditions).
  • g_form.getValue(varName) gives the user's answer; blank answers are skipped.
  • g_form.setValue('u_desc_collector', description) places the final text in the collector variable which is mapped to current.description.

Minimal Record Producer (server) script

 

If you mapped u_desc_collector to the description field in step 1, you don’t need server-side code. If you prefer to set current.description in the producer script, use this:

 

(function runProducerScript(producer, current) {
  // producer.u_desc_collector contains the client-built value
  var collected = producer.u_desc_collector;
  if (collected && collected.toString().trim() !== '') {
    current.description = collected.toString();
  }
})(producer, current);

 

Service Portal note

  • If your record producer is used in Service Portal, the same approach works — g_form.getEditableFields() and g_form.getValue() are available in portal catalog forms.
  • If using a custom SPA widget to submit, replicate the logic in the widget’s client controller and add the u_desc_collector property to the data you send to the server.

If my answer helped you, please consider marking it as Correct and giving it a 👍 Helpful — it might help other members in the community too!

Thanks,


Astik T
ServiceNow Community Rising Star 2025 🌟😊💡