ServiceNow field guide
GlideAjax, Simplified
Learn GlideAjax with simple analogies and a visual lab to understand the exchange between Client Script, GlideAjax, and Script Include.
First check: is there Low-code or OOTB?
Before spinning up a GlideAjax or any hardcoded solution, be brutally honest: does the platform already solve this? A Flow Designer, Integration Hub, Data Lookup, or even an OOTB component often delivers 80–100% of the requirement with far less effort and maintenance.
-
1Map the requirement: describe what the user needs, process context, and the rules already in place.
-
2Inventory your options: review OOTB catalogs, Store apps, and low-code resources before drafting a custom architecture.
-
3Justify the custom build: if you still need code, document the reasons (functional gaps, performance, compliance) and proceed intentionally.
That discipline saves time, keeps you aligned with ServiceNow best practices, and avoids needless legacy. When OOTB/low-code can’t cover it, that’s the moment to go hardcode.
Important
For learning purposes I picked a very simple scenario: fetching the user’s email via script. In a real project you’d solve this with Dot-Walking (showing related table fields) instead of coding. I chose this flow because it is clear and lightweight, so we can focus 100% on GlideAjax syntax without complex business logic distractions.
Why GlideAjax exists
GlideAjax is the safe bridge between the Client Script and the Script Include. It lets you pull server data without freezing the UI, respects ACLs, and cuts unnecessary backend calls.
-
1Performance: asynchronous calls keep the user working while the response is on its way.
-
2Security: Script Include ACLs stay in charge and block direct DB access.
-
3Flexibility: return strings, JSON objects, or whatever payload the client must render.
Concept: The Asynchronous Waiter
The browser (Client Side) cannot touch the database directly for security and performance reasons. To request data from the server without reloading or freezing the page, we use GlideAjax as the middle person.
1. Client (Table)
You (Client Script) place the order at the table. No direct access to the kitchen (Database).
2. GlideAjax (Waiter)
Carries the order (parameters) and brings back the dish (XML/JSON). The guest keeps chatting while they wait (asynchronous).
3. Server (Kitchen)
The Chef (Script Include) receives the order, queries the stock (DB) safely, and prepares the response.
GlideAjax Interactive Lab
Test GlideAjax below. Change the Caller field and watch the kitchen animation plus the logs happening in real time.
Waiting for a change on the form...
Rotate the screen to use the simulator
Almost there! This device has enough height—just switch it to landscape to unlock the GlideAjax interactive lab.
Simulator available only on tall screens
To experience the interactive lab, open this guide on a device with at least 900 px of height (desktop, laptop, or tablet in landscape). You can still follow the full theory on mobile.
Step 1: The Backend (Script Include)
How to create it in ServiceNow
-
1Navigate to System Definition > Script Includes.
-
2Click New.
-
3Set the Name (e.g., UserDataHelper). Keep it handy!
-
4IMPORTANT: Check Client callable. Without it, the browser can’t call this script.
var UserDataHelper = Class.create();
UserDataHelper.prototype = Object.extendsObject(AbstractAjaxProcessor, {
// Function name exposed to the client
getEmail: function() {
// 1. Capture the parameter (snake_case by convention)
var userId = this.getParameter('sysparm_user_id');
if (!userId) return '';
// 2. Use GlideRecord to query the target table
var gr = new GlideRecord('sys_user');
if (gr.get(userId)) {
// 3. Return the value via getValue (more performant)
return gr.getValue('email') || '';
}
return '';
},
type: 'UserDataHelper'
});
Step 2: The Frontend (Client Script)
How to create it in ServiceNow
-
1Go to System Definition > Client Scripts.
-
2Click New.
-
3Fill out: Table = Incident, Type = onChange, Field name = Caller.
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading) return;
// 1. Clear the field if the user removes the caller (avoid orphan data)
if (newValue === '') {
g_form.setValue('u_email', '');
return;
}
// 2. Instantiate GlideAjax with the Script Include NAME
var ga = new GlideAjax('UserDataHelper');
// 3. Tell it which FUNCTION to run
ga.addParam('sysparm_name', 'getEmail');
// 4. Send the parameters (use consistent naming)
ga.addParam('sysparm_user_id', newValue);
// 5. Fire the async call (getXMLAnswer is the modern default)
ga.getXMLAnswer(function(answer) {
// Guard against null/undefined
g_form.setValue('u_email', answer || '');
});
}
ga.getXMLWait(). It locks the user’s browser until the server answers and creates terrible UX.
Golden Tips
-
1Use getXMLAnswer: Back then we used
getXMLand had to parse XML manually.getXMLAnsweralready returns the clean string. -
2JSON for complex payloads: Need to send Email, Phone, and Title together? Don’t fire three GlideAjax calls. Return one JSON object (
JSON.stringify) and parse it on the client (JSON.parse).
Reference material
Explore official docs and community content to deepen your GlideAjax knowledge and keep your implementations aligned with platform best practices.
-
Official documentationOpen
The latest ServiceNow GlideAjax documentation covering methods, parameters, and examples.
-
Community article on GlideAjaxOpen
Great article by Shawn Dowler with a practical example and a clean explanation of the parameters.