Goran WitchDoc
ServiceNow Employee
ServiceNow Employee

servicenow_glideajax_getreference_background.jpg

 

We’ve all been there. You need a quick lookup, so you reach for getReference(). It works… until the form slows down and the complaints start piling up.

I still remember the day I leaned a little too hard on getReference(). It was a new onboarding workflow, and the requirement sounded simple: populate a few fields when the hiring manager is selected. Easy, right?

So, I sprinkled in a couple of g_form.getReference() calls—five of them, to be exact. Lookups on manager, department, cost center, location, and role. By the time I was done, the form looked fine in testing. But once it hit production, the complaints started rolling in:

“Why does this form take forever to load?”

Yeah… turns out five getReference() calls in a row is less “clever shortcut” and more “death by a thousand GlideRecord queries.” Lesson learned.


Why This Happens

g_form.getReference() feels like the duct tape of ServiceNow client development. Quick fix, sticks to anything, solves the problem, until it doesn’t.

 

  • How it works: It fetches the entire referenced record asynchronously and passes it to your callback.
  • The problem: It doesn’t care that you only needed the location field, you’re pulling in every column of the user record. Multiply that by a few calls, and suddenly your form is making round trips that add noticeable lag.

 

A simple example:

g_form.getReference('caller_id', function(caller) {
  g_form.setValue('u_location', caller.location + '');
}); 

Perfectly fine in a small lookup. Dangerous at scale.


GlideAjax to the Rescue

Now, GlideAjax isn’t as instant-gratification as getReference(). You need a Script Include, you need to define what comes back, and you need to think a little harder. But here’s the kicker: you control the payload.

Client script:

var ga = new GlideAjax('GetCallerInfo');
ga.addParam('sysparm_name','getBasics');
ga.addParam('sysparm_user', g_form.getValue('caller_id'));
ga.getXMLAnswer(function(ans){
  var data = JSON.parse(ans);
  g_form.setValue('u_location', data.location, data.locationDisplay);
}); 

Script Include:

var GetCallerInfo = Class.create();
GetCallerInfo.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
  getBasics: function() {
    var id = this.getParameter('sysparm_user');
    var gr = new GlideRecordSecure('sys_user'); // ACLs enforced
    if (!gr.get(id)) return JSON.stringify({ error: 'not_found' });
    return JSON.stringify({ location: gr.getValue('location'), locationDisplay: gr.getDisplayValue('location') });
  },
  isPublic: function() { return true; }
}); 

Now you’re fetching exactly what you need, honoring ACLs, and keeping the form snappy.


Rule of Thumb (From the School of Hard Knocks)

 

  • One field, one time, small table? getReference() is fine.
  • Multiple lookups, big tables, or production-grade flows? GlideAjax is the grown-up choice.
  • Values always needed on load? Preload them with g_scratchpad in a Display Business Rule—faster, cleaner, safer.

 


My Takeaway

getReference() is like grabbing fast food, great when you’re in a hurry, but you can’t build a diet on it. GlideAjax is the proper kitchen setup: takes a little prep, but it scales when you’ve got to feed a crowd.


Your Turn

Have you ever regretted leaning on getReference() after a form slowed to a crawl? What tipped you toward switching to GlideAjax?


//Göran
Author:
Witch Doctor's Playbook: ServiceNow AI
The Witch Doctor's Guide To ServiceNow 

Version history
Last update:
2 hours ago
Updated by:
Contributors