John Caruso
Kilo Guru
 
After many months seeking enlightment and inspiration for continuing this series of articles, we're finally ready to continue our functional journey!

(Or, I'm just a lazy guy who procastinated for far too long... ;-))

In Part 1, we created a simple query helper function that separated GlideRecord query and looping logic from record-level processing logic.

For this article, we'll review some record-level processing logic and as we did before, look for opportunities to factor out repeated, boilerplate code.

Here's some real world code (adapted from HAAPIs script include):
function ex_1() {
    var gr = new GlideRecord('sys_cluster_state');
    gr.get('status', 'online');

    var lastDate = gr.most_recent_message.getGlideObject().getRaw();
    var lastDateSecs = (new Packages.java.util.Date().getTime() - lastDate.getTime()) / 1000;
    var nodeConfig = {
        sys_id: gr.sys_id.toString(),
        system_id: gr.system_id.toString(),
        status: gr.status.toString(),
        last_checkin: gr.most_recent_message.toString(),
        last_checkin_friendly: GlideDateUtil.getDateTimeString(lastDateSecs, true)
    };

    return nodeConfig;
}
 
We'll cleanup some of the old Legacy API code too, but did you notice some repeated code related to GlideRecord? Yes, the `.toString()` calls on each of the fields being mapped to the nodeConfig object.

Alternatively, you may see the `gr.system_id + ''` technique, or perhaps `gr.getValue('system_id')`.

If you're not aware, these are all methods to get a string representation of the underlying value encapsulated by the GlideElement object - which is what is returned when you access a GlideRecord property (field).

We often need a string value (or non-reference type) to ensure we get a "copy" of the GlideElement value, rather than a reference to the GlideElement itself - which remains constant while looping over a set of GlideRecords, and often results in unexpected behavior.

Wouldn't it be nice if GlideRecord just returned values instead of GlideElement references? Well, that's a topic for another day, but for now, let create a little helper function to do just that.
function mapGR(gr) {
    function mapField(obj, field) {
        obj[field] = gr[field].toString();
        return obj;
    }
    var fields = Object.keys(gr).sort();
    return fields.reduce(mapField, {});
}
 
Let's clean up and refactor our first example to use the mapGR function:
function ex_2() {
    var gr = new GlideRecord('sys_cluster_state');
    gr.get('status', 'online');
    var node = mapGR(gr);

    var lastDate = new GlideDateTime(gr.most_recent_message).getNumericValue();
    var lastDateSecs = Math.floor((Date.now() - lastDate) / 1000) + ' seconds';
    var nodeConfig = {
        sys_id: node.sys_id,
        system_id: node.system_id,
        status: node.status,
        last_checkin: node.most_recent_message,
        last_checkin_friendly: lastDateSecs
    };

    return nodeConfig;
}
 
Looks a bit cleaner without the `.toString()` cruft in our code, eh?

Next time, we'll enhance the mapGR function to do even more declarative and functional stuff.
Version history
Last update:
‎10-06-2019 10:48 AM
Updated by: