← back

Scripting Guide

GlideRecord • Business Rules • Client Scripts • GlideAjax

type your answer • check what you know
0 / 15 attempted
All
GlideRecord
Business Rules
Client-Side
GlideAjax
APIs
01
What is a GlideRecord and how do you write one from scratch?
gliderecord
+
5 key points
Key Points
GlideRecord is a server-side API for querying / manipulating table data
new GlideRecord('table_name') — instantiate with table name
addQuery() to filter, then query() to execute
while (gr.next()) to iterate through results
Access field values with gr.field_name inside the loop
💬 Full Answer
GlideRecord is the server-side API for querying and manipulating records in ServiceNow tables. It follows a consistent 5-step pattern:
var gr = new GlideRecord('incident'); // 1. Pick table gr.addQuery('state', 1); // 2. Filter gr.query(); // 3. Execute while (gr.next()) { // 4. Loop gs.info(gr.short_description); // 5. Do something }
You can also use addOrCondition() for OR logic, addEncodedQuery() to paste filter URLs, and get() to grab a single record by sys_id without needing query().
💡 In an interview, write this pattern out on paper or whiteboard first — it shows you know the fundamentals cold.
02
Explain dot-walking. When would you need it?
gliderecord
+
4 key points
Key Points
Reference fields store a sys_id, not the display value
Dot-walking lets you traverse reference fields to reach related record data
Example: assigned_to.name or assignment_group.manager.email
Can chain multiple dot-walks for deep references
💬 Full Answer
Reference fields in ServiceNow store a sys_id — not a name or display value. So if you do gr.addQuery('assigned_to', 'Fred Luddy'), it won't work because you're comparing a sys_id to a string.

Dot-walking lets you traverse through reference fields to reach the actual data:
// WRONG — comparing sys_id to a string gr.addQuery('assigned_to', 'Fred Luddy'); // RIGHT — dot-walk to the name field gr.addQuery('assigned_to.name', 'Fred Luddy'); // Chain them for deeper references gr.addQuery('assignment_group.manager.email', '[email protected]');
⚠ Interview favourite — if they ask about reference fields, always bring up dot-walking and sys_ids.
03
Walk me through GlideRecord CRUD operations.
gliderecord
+
4 key points
Key Points
Create: initialize(), set fields, insert()
Read: get(sys_id) or addQuery + query + next
Update: get the record, set fields, update()
Delete: get the record, deleteRecord()
💬 Full Answer
// CREATE var gr = new GlideRecord('incident'); gr.initialize(); gr.short_description = 'New issue'; gr.insert(); // READ gr.get(sys_id); gs.info(gr.short_description); // UPDATE gr.get(sys_id); gr.state = 2; gr.update(); // DELETE gr.get(sys_id); gr.deleteRecord();
💡 Notice get() doesn't need query() — it fetches a single record directly by sys_id.
04
What is an encoded query and why would you use one?
gliderecord
+
3 key points
Key Points
A string representation of a filter — can copy from the list filter URL
Use addEncodedQuery() to apply complex filters in one line
Cleaner than chaining multiple addQuery calls for complex conditions
💬 Full Answer
An encoded query is a string representation of a filter condition. You can grab one from the ServiceNow list filter URL, or right-click the breadcrumb and choose "Copy query." It's useful for complex filters because it keeps your code clean:
var gr = new GlideRecord('incident'); gr.addEncodedQuery('state=1^priority=1^assigned_toISNOTEMPTY'); gr.query();
Instead of writing three separate addQuery() calls, you get it all in one line. It's also easier to test — just paste the encoded query string back into a list filter to verify it.
05
What's the difference between Before and After business rules?
rules
+
4 key points
Key Points
Before = runs before the database write
After = runs after the write is committed
Before: set field values, validate — no need to call update()
After: trigger events, create related records, send notifications
💬 Full Answer
A Before business rule runs before the record is written to the database. It's ideal for setting field values or validating data — and importantly, you don't need to call update() because the system hasn't saved yet, so your changes get included in the same write.

An After business rule runs after the commit. Use it for anything that depends on the record already existing — like triggering events, creating child records, or sending notifications.

There's also Async — runs after the write but in the background. Use it for heavy processing that shouldn't slow the user down.
⚠ Classic trap: calling current.update() inside a Before rule — it causes a double-save and can trigger infinite loops.
06
What's the difference between current and previous?
rules
+
3 key points
Key Points
current = the record as it is now (with changes about to be saved)
previous = the record values before the current change
Use together to detect field changes: current.state != previous.state
💬 Full Answer
In a Business Rule, current represents the record being acted on — it contains the new values about to be saved. previous holds the values from before the change. Together they let you detect what changed:
if (current.state != previous.state) { gs.info('State changed from ' + previous.state + ' to ' + current.state); }
This is essential for writing business rules that only fire on specific field changes rather than on every update.
07
How do you prevent a record from being saved in a Business Rule?
rules
+
3 key points
Key Points
Use current.setAbortAction(true) to stop the save
Must be in a Before business rule (data hasn't been written yet)
Pair with gs.addErrorMessage() to tell the user why
💬 Full Answer
Use current.setAbortAction(true) in a Before business rule. Since it runs before the database write, you can cancel the operation entirely. Always pair it with an error message so the user knows what happened:
if (!current.short_description) { current.setAbortAction(true); gs.addErrorMessage('Short description is required'); }
⚠ This only works in Before rules — in an After rule the data is already committed.
08
Name all the script types in ServiceNow and where each runs.
rules
+
5 key points
Key Points
Business Rule — server, on insert/update/delete
Client Script — browser, onLoad/onChange/onSubmit
Script Include — server, on demand (reusable functions)
Scheduled Job — server, time-based
UI Action / UI Policy / Fix Script
💬 Full Answer
Server-side: Business Rules (before/after/async database operations), Script Includes (on-demand reusable functions), Scheduled Jobs (time-based), Fix Scripts (manual one-time runs), UI Actions (can be both — button/link clicks).

Client-side: Client Scripts (onLoad, onChange, onSubmit), UI Policies (condition-based form control — no code needed).

Knowing which runs where is critical — it tells you what APIs are available and what you can access.
💡 Quick rule: if it uses g_form it's client. If it uses GlideRecord or current, it's server.
09
Client Script vs UI Policy — when would you use each?
client
+
4 key points
Key Points
UI Policy = no-code, condition-based (show/hide, mandatory, read-only)
Client Script = code-based, more flexibility (onLoad, onChange, onSubmit)
Prefer UI Policy for simple form control — easier to maintain
Client Script when you need logic, validation, or g_form methods beyond show/hide
💬 Full Answer
UI Policy is the no-code option — you set conditions and actions (show/hide fields, make mandatory, set read-only) without writing JavaScript. Use it when your logic is straightforward condition → action.

Client Script gives you full JavaScript control. Use it when you need custom logic, complex validation on submit, or need to call g_form methods that UI Policy doesn't cover (like showFieldMsg or addErrorMessage).

Rule of thumb: always try UI Policy first. It's easier to maintain, easier for other admins to understand, and less likely to break during upgrades.
10
Name five g_form methods and what each does.
client
+
5 key points
Key Points
getValue() — get a field's value
setValue() — set a field's value
setVisible() — show or hide a field
setMandatory() — make a field required
setReadOnly() or addErrorMessage() or showFieldMsg()
💬 Full Answer
g_form.getValue('state'); // Get field value g_form.setValue('priority', 1); // Set field value g_form.setVisible('notes', true); // Show/hide field g_form.setMandatory('notes', true); // Make required g_form.setReadOnly('caller_id', true); // Make read-only g_form.addErrorMessage('Fix errors'); // Error on form g_form.showFieldMsg('state', 'Check', 'info'); // Msg on field
11
Why should you never use GlideRecord on the client side?
client
+
3 key points
Key Points
Client-side GlideRecord makes synchronous HTTP calls — blocks the browser
Bad UX: user sees freezing/lag while the call completes
Use GlideAjax instead — it's asynchronous
💬 Full Answer
Using GlideRecord on the client side makes synchronous HTTP calls to the server. That means the browser freezes until the response comes back — terrible user experience, especially on slow networks. It also exposes table structures to the browser.

The correct approach is GlideAjax — it makes asynchronous calls to a Script Include on the server, gets the data you need, and returns it via a callback without blocking the UI.
💡 This is a very common interview question. The answer they want: "GlideAjax — always."
12
How does GlideAjax work? Walk me through both sides.
glideajax
+
5 key points
Key Points
Server side: Script Include extending AbstractAjaxProcessor
Server function returns a value (the data you need)
Client side: new GlideAjax('ScriptIncludeName')
addParam('sysparm_name', 'functionName') to specify which method
getXMLAnswer(callback) — asynchronous, use the callback
💬 Full Answer
GlideAjax is a two-part pattern — server + client:

Step 1 — Script Include (server):
var MyAjax = Class.create(); MyAjax.prototype = Object.extendsObject( AbstractAjaxProcessor, { getIncidentCount: function() { var gr = new GlideRecord('incident'); gr.addQuery('state', 1); gr.query(); return gr.getRowCount(); }, type: 'MyAjax' });
Step 2 — Client Script (browser):
var ga = new GlideAjax('MyAjax'); ga.addParam('sysparm_name', 'getIncidentCount'); ga.getXMLAnswer(function(answer) { alert('Count: ' + answer); });
⚠ GlideAjax is asynchronous — always use the callback. Never assume the answer is available on the next line.
13
What does the Script Include need to extend for GlideAjax, and why?
glideajax
+
3 key points
Key Points
Must extend AbstractAjaxProcessor
This makes the Script Include callable from the client via AJAX
"Client callable" checkbox must be ticked on the Script Include form
💬 Full Answer
The Script Include must extend AbstractAjaxProcessor. This base class provides the framework for receiving AJAX requests from the client side and returning data. Without it, the GlideAjax call from the browser wouldn't know how to route to your function.

You also need to tick the "Client callable" checkbox on the Script Include form — this is a security gate that explicitly allows client-side access.
14
Name five common server-side APIs and what each does.
api
+
5 key points
Key Points
gs.info() — log to system log
gs.getUser() — get current logged-in user
gs.hasRole() — check user role
gs.addInfoMessage() / gs.addErrorMessage() — blue/red banners
current.setAbortAction(true) — stop save in Before rules
💬 Full Answer
gs.info('message'); // Log to system log gs.getUser().getFullName(); // Current user's name gs.hasRole('admin'); // Check user role gs.addInfoMessage('Saved!'); // Blue info banner gs.addErrorMessage('Error!'); // Red error banner current.setAbortAction(true); // Stop save (Before rules)
15
What's the difference between synchronous and asynchronous Business Rules?
api
+
4 key points
Key Points
Synchronous (Before/After) = runs in the current transaction, user waits
Asynchronous = runs in the background after the transaction completes
Async is for heavy/slow processing that shouldn't block the user
Async cannot abort actions or set field values on the current record
💬 Full Answer
Synchronous rules (Before and After) run within the same database transaction. The user has to wait for them to complete before the form reloads. Before rules can modify the record and abort the save; After rules can create related records and trigger events.

Asynchronous rules run in the background after the transaction is fully committed. They're queued as a separate job. Use them for heavy processing — like sending emails, making REST calls, or running large queries — so the user isn't stuck waiting.

Trade-off: Async rules can't modify the current record (it's already saved) and can't abort the transaction.