Template literals in ServiceNow

Dennis R
Tera Guru

Hey all,

I'm trying to figure out how to programmatically use what in JavaScript are referred to as "template literals."

 

In other words, if I have a string variable called source that contains the text, "The next change is ${change.number}," and I have a value of, for example, "CHG0025493," I need some way to programmatically plug that value into the source string.

 

I know that ServiceNow has some way to do this, this functionality is used, for example, in mail notificaiton scripts. The picture in the documentation on this page is hard to see, but if you look at the script, you can see that it's using ${sys_updated_on}, which gets the update time of the record plugged into it.
https://docs.servicenow.com/bundle/london-servicenow-platform/page/administer/notification/task/t_Ed...

 

A more advanced example of an entire expression being evaluated is here:

https://docs.servicenow.com/bundle/london-servicenow-platform/page/administer/notification/concept/c...

 

So it is doable, at least in the back end. I strongly suspect that this functionality might exist in the front end, but just isn't documented. In plain ol' JavaScript, the mechanism for evaluating such strings is called a template literal, described here:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals

 

Unfortunately, when I try to use a template literal within a ServiceNow script, I get a "Javascript compiler exception: illegal character" error. I could manually swap strings in an out using something like regular expressions with JavaScript's String.replace() method, but the work and kuginess involved in implementing such a thing kind of defeats the point of wanting to use template literals in the first place.

 

Does anyone know of any way to implement the equivalent functionality of template literals in our own ServiceNow scripts?

6 REPLIES 6

vkachineni
Kilo Sage
Kilo Sage

Any one has a code snippet to use template literals?

Please mark Correct and click the Thumb up if my answer helps you resolve your issue. Thanks!
Vinod Kumar Kachineni
Community Rising Star 2022

The code snippet below:

Script Include 'RecordToHTML2' (copied from OOTB RecordToHTML)

gs.include("PrototypeServer");

// Modifed by Paul Morris to show display values and variables

/**
 * Utility class to turn a record in a table into HTML.
 * 
 * Tom Dilatush tom.dilatush@service-now.com
 */
var RecordToHTML2 = Class.create();

RecordToHTML2.prototype = {
    
    /*
     * Initializes a new instance of this class.
     * 
     * table: the name of the table from which this record comes
     * sys_id: the sys_id of the record
     * pattern: the pattern of the string we want to generate.  The pattern may include ${} escapes for fields whose values should
     *          be included.  For instance, the pattern "sys_id: ${sys_id}" would substitute the actual sys_id's value for the escape.
     * link: a boolean, true if the pattern is to be surrounded by an "a" tag to link to the object in question.
     */
    initialize: function(table, sys_id, pattern, link) {
        this.table = table;
        this.sys_id = sys_id;
        this.pattern = pattern;
        this.values = {};
        this.link = link;
        this.values['sys_id'] = sys_id;
    },
    
    /*
     * Set a field value.  This is useful if the calling code has already read the underlying GlideRecord, and wants to avoid
     * the overhead of another database read.
     */
    setValue: function(name, value) {
        this.values[name] = value;
    },
    
    /*
     * Converts this instance to a string.
     */
    toString: function() {
        // some setup...
        var gr = new GlideRecord(this.table);
        var gr_read = false;
        var regex = /^(.*?)\$\{([^\}]+?)\}(.*)$/;
        
        // make all our escape substitutions...
        var rr = regex.exec(this.pattern);
        while (rr) {
            var fn = rr[2];
            var fv = this.values[fn];
            if (!fv) {
                if (!gr_read) {
                    gr.get(this.sys_id);
                    gr_read = true;
                }
				if (fn.indexOf('variables.') > -1) {
					var varName = fn.split('variables.')[1];
					fv = gr.variables[varName].getDisplayValue();
				} else {
					fv = gr[fn].getDisplayValue(); //Modified to show display value
				}
                this.values[fn] = fv;
            }
            this.pattern = rr[1] + fv + rr[3];
            rr = regex.exec(this.pattern);
        }
        
        // surround with an "a" tag, if this is to be a link...
        if (this.link)
            this.pattern = '<a href="' + this.table + '.do?sys_id=' + this.sys_id + '"><u>' + this.pattern + '</u></a>';
        
        return this.pattern;
    },
    
    type: 'RecordToHTML2'
}

Usage

//Load record as test
var gr = new GlideRecord('sc_req_item');
gr.get('2e129da5db21f700f659126b3a96196d');

var str = "${sys_class_name} ${number} has a state of ${state} created on ${sys_created_on} with a variable description of ${variables.description}";

var r2html = new RecordToHTML2(
  gr.getTableName(),
  gr.getValue('sys_id'),
  str);

//Output
r2html

Output

Requested Item RITM0031841 has a state of In Progress created on 21/05/2019 10:11:05 with a variable description of a

ServiceNow Nerd
ServiceNow Developer MVP 2020-2022
ServiceNow Community MVP 2019-2022