logo

NJP

Client Side Scripting: Go for GlideAjax (with getXMLAnswer)!

Import · Jan 10, 2020 · article

Articles, Blogs, Videos, Podcasts, Share projects - Experiences from the field

Hi there,

Community questions on Client Side scripting to retrieve data, often answers are giving suggestions to use GlideAjax. GlideAjax (with getXMLAnswer) absolutely being the best method for retrieving data Client Side.

Though somehow a lot developers are using techniques like GlideRecord, getReference or getReference with a callback. Obviously, this could be because of someone is new in the ServiceNow eco-system and just hasn't touched on this subject yet. Or it could be the developer is just lazy image. Or could it be that answers and articles on the Community on this subject (and there are loads of them!) are not clear enough or hard to find?

Well, I'll give it a go to explain some basic GlideAjax examples (with getXMLAnswer). In a later article I'll explain our dynamic GlideAjax functionality. Also, I'll add some hints to make the scripting a lot easier.

Client Side Scripting

First, let's explain why GlideAjax is mentioned so often. Why not just use one (1) line of code with GlideRecord getReference? Or five (5) lines of code with GlideRecord? Those are so easy to set up, so why not?!

You might have seen the table below already somewhere (not mine: Paul Morris!). The table is a good visualization of Simplicity versus Efficiency.

API Simplicity Efficiency Description
GlideRecord getReference 1st 5th - 1 line of code- Poor UX (blocks browser)- Returns entire record
GlideRecord 2nd 4rd - ~ 5 lines of code- Poor UX (blocks browser)- Returns entire record
GlideRecord getReference(with callback) 3rd 3rd - 5-10 lines of code (with callback)- Best UX (does not block browser)- Returns entire record
GlideRecord(with callback) 4th 2nd - ~ 10 lines of code (with callback)- Best UX (does not block browser)- Returns entire record
GlideAjax 5th 1st - ~20 lines of code (Client Script + Script Include)- Best UX (does not block browser)- Returns only the data you need

Bad Practice

Looking at the above table, GlideRecord getReference, and GlideRecord are for sure not done. No explanation needed. Yes, one (line) of code could do, though efficiency-wise a really poor choice. Just don't go this road.

Poor Practice

Looking at the above table, GlideRecord getReference (with callback), and GlideRecord (with callback) are UX wise fine. Though, these still return the entire record. getRefence (with callback) is used a lot, though there is a better way.

Best practice

GlideAjax tops the efficiency chart. Make a habit of using this. So why is GlideAjax actually often not a habit to use? Well simply because developers are not familiar with this, that it takes a lot more lines of code instead of the really simple GlideRecord getReference, that it takes two (2) artifacts (a (Catalog) Client Script, and a Script Include).

Note: Actually I would change "GlideAjax" into "GlideAjax (with getXMLAnswer)". GlideAjax with getXML still would return a whole document. While GlideAjax with getXMLAnswer would only return the exact answer you need. Read about this in one of my previous articles: getXMLAnswer vs getXML.

Later in this article I'll give two (2) hints on how to make life for you as a developer easier, not having to write out all the code over and over. Also in a later article, I'll share our dynamic GlideAjax set up which can potentially be used on every field on every table through your instance without additional maintenance.

GlideAjax examples

1) We would like to retrieve the Phone number of a Caller selected. Phone number should be written to a custom Phone number field on the Incident form (u_phone).

Script Include

Name: getUserPropertiesAjaxClient callable: true

Script:

var getUserPropertiesAjax = Class.create();
getUserPropertiesAjax.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    get_phone : function() {
        var grUser = new GlideRecord('sys_user');

        if(grUser.get(this.getParameter('sysparm_user'))) {
            return grUser.getValue('phone');
        }
    },

    type: 'getUserPropertiesAjax'

});

Client Script

Table: IncidentType: onChangeField name: Caller

Script:

function onChange(control, oldValue, newValue, isLoading, isTemplate) {

    if(isLoading) {
        return;
    }

    if(newValue === '') {
        g_form.clearValue('u_phone');
    }

    var gaPhone = new GlideAjax('getUserPropertiesAjax');
    gaPhone.addParam('sysparm_name', 'get_phone');
    gaPhone.addParam('sysparm_user', newValue);
    gaPhone.getXMLAnswer(_handleResponse);

    function _handleResponse(response) {
        var answer = response;

        g_form.setValue('u_phone', answer);
    }

}

2) We would like to retrieve the Location of a Caller selected. Location should be written to the out-of-the-box Location field on the Incident form (location).

Script Include

We'll just add a function "get_location" to the Script Include created earlier.

Script:

var getUserPropertiesAJAX = Class.create();
getUserPropertiesAJAX.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    get_phone : function() {
        var grUser = new GlideRecord('sys_user');

        if(grUser.get(this.getParameter('sysparm_user'))) {
            return grUser.getValue('phone');
        }
    },

    get_location : function() {
        var grUser = new GlideRecord('sys_user');

        if(grUser.get(this.getParameter('sysparm_user'))) {
            var answer = {};
            answer.value = grUser.getValue('location');
            answer.displayValue = grUser.getDisplayValue('location');
            return JSON.stringify(answer);
        }
    },

    type: 'getUserPropertiesAJAX'

});

Note: Instead of just returning "return grUser.getValue('location')", we are actually returning the getValue and the getDisplayValue. This is because g_form.setValue(), for a Reference field expects the value AND the display value. If only returning the value (the sys_id), an additional Server call will be performed (and the efficiency reason for why performing GlideAjax would then actually be lost).

Client Script

Table: IncidentType: onChangeField name: Caller

Script:

function onChange(control, oldValue, newValue, isLoading, isTemplate) {

    if(isLoading) {
        return;
    }

    if(newValue === '') {
        g_form.clearValue('location');
    }

    var gaLocation = new GlideAjax('getUserPropertiesAJAX');
    gaLocation.addParam('sysparm_name', 'get_location');
    gaLocation.addParam('sysparm_user', newValue);
    gaLocation.getXMLAnswer(_handleResponse);

    function _handleResponse(response) {
        var answer = JSON.parse(response);
        g_form.setValue('location', answer.value, answer.displayValue);
    }

}

Note: When using the Script Editor, notice the information on g_form.setValue:

image

Making life easier

So is there anything we can do about the downside of going for the top-ranked efficiency, which actually brings bottom-ranked simplicity?

1) Set up example (Catalog) Client Scripts

Client Scripts which you could simply "Insert and Stay", and modify. No need to write all the code out again.

2) Syntax Editor Macros

Write example GlideAjax call ones and save it in a Syntax Editor Macro. Syntax Editor Macros can easily be called within a Script field. Read about this in one of my previous articles: Expanding Syntax Editor Macros.

Dynamic GlideAjax

You might already notice, the functions in the Script Include can be used over and over, nice. Though for example, if you would now like to get your hands on the Email value of the User record, you would have to add a function again.

This can be done easier image I will share a Dynamic usage of GlideAjax in a future Community Article.

Platform UI, Service Portal / Client Script, Catalog Client Script

The usages of GlideAjax and the Script Include and Catalog Client Script, do work both for Platform UI and Service Portal. As example, I simply used the Incident form on the Platform UI, and therefor a Client Script. Using the exact same Script Include and GlideAjax scripting within Catalog Client Scripts should work fine.

---

And that's it actually. Hope you like it. If any questions or remarks, let me know!

Kind regards,

Mark Roethof

ServiceNow Technical Consultant @ Quint Technology

---

LinkedIn

image

View original source

https://www.servicenow.com/community/developer-articles/client-side-scripting-go-for-glideajax-with-getxmlanswer/ta-p/2324830