The Now Platform® Washington DC release is live. Watch now!

Help
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
SlightlyLoony
Tera Contributor

find_real_file.pngHave you ever written a handy-dandy little script function, and then wished you could have it accept different kinds of arguments? For instance, perhaps you wrote a function that took a list of people's first and last names (in an array of two-element arrays) that figured out how many characters were in the longest combinations. Cool! Then you realize that you could make that function even more generally useful if it could also accept a GlideRecord with first and last name fields. But is it really possible to make a single function that could accept either form of argument?

Why, yes it is!

Consider this test code:


gs.log('Method 1: string argument');
var nicGR = new GlideRecord('cmdb_ci_network_adapter');
nicGR.addQuery('ip_address', '10.10.10.135');
nicGR.query();
if (nicGR.next()) {
var cis = getCIs(nicGR.cmdb_ci);
while (cis.next())
gs.log(' ' + cis.name);
}

gs.log('Method 2: GlideRecord argument');
var nicGR = new GlideRecord('cmdb_ci_network_adapter');
nicGR.addQuery('ip_address', '10.10.10.135');
nicGR.query();
var cis = getCIs(nicGR, 'cmdb_ci');
while (cis.next())
gs.log(' ' + cis.name);

gs.log('Method 3: Array of sys_ids argument');
var sysIDs = [];
sysIDs.push('d48740560a0a3c19009fcd0945f91624');
var cis = getCIs(sysIDs);
while (cis.next())
gs.log(' ' + cis.name);

gs.log('Method 4: function argument');
var cis = getCIs(getNICs, 'cmdb_ci');
while (cis.next())
gs.log(' ' + cis.name);

function getNICs() {
var nicGR = new GlideRecord('cmdb_ci_network_adapter');
nicGR.addQuery('ip_address', '10.10.10.135');
nicGR.query();
return nicGR;
}

When I run it on my instance, it produces:

Method 1: string argument
sanops05
Method 2: GlideRecord argument
sanops05
Method 3: Array of sys_ids argument
sanops05
Method 4: function argument
sanops05

In each of the four pieces of the test code, the getCIs() method is called — each time with a different type of first argument. Yet each time it produces the same result. Somehow this function knew how to behave no matter what type of argument it got. Here's how it knew:

function getCIs(source, field) {
// get ourselves a list of CI sys_id values...
if (typeof source == 'function')
source = source();
var sysIDs = [];
if (source instanceof GlideRecord) {
if (!field)
return null;

while (source.next())
sysIDs.push('' + source.getValue(field));
} else if (source instanceof Array)
sysIDs = source;
else
sysIDs.push('' + source);

// now we'll do the actual work, with an array of sys_ids...
var gr = new GlideRecord('cmdb_ci');
gr.addQuery('sys_id', sysIDs);
gr.query();
return gr;
}


The first part of the function figures out what kind of argument it got, and then does what it needs to do to turn that argument into an array of sys_ids. The second part simply takes that list of sys_ids and queries for them. So all the magic is happening in the first part.

In that code, the first thing it does is check to see if the source argument is a function. If so, it executes the function and replaces source with the result. In other words, it's assuming that if someone passed it a function, they must want us to get our source from it. The next bit figures out whether source is a GlideRecord (in which case we iterate through it, collecting sys_ids from the specified field), an Array (in which case we assume we got a list of sys_ids), or something else (in which case we assume we got a single sys_id, so we stuff it into an array).

The way we figure out what kind of argument we got is by careful use of the typeof and instanceof operators. Both are standard features of JavaScript, documented at the preceding links. Be sure to read that documentation carefully — these operators may not work exactly as you'd expect!