Dot walking through multiple tables in client script

Kyle Wiley
Mega Expert

I am trying to dot walk through multiple tables in an onChange client script on the Incident table.  When the Caller field on the INC form changes, I want to reference the sys_user table to see what department the Caller is in.  The field that I am trying to use on the Department table is u_department_group.

 

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

   if (isLoading || newValue === '') {

      return;

   }

var caller = g_form.getReference('caller_id');

var dept = g_form.getReference('caller_id').department;

   if (newValue) {

  confirm(caller.name);

  confirm(dept);

   }

}

 

caller.name prints out the user's full name as it displays in the sys_user table but when I try to print out dept, the only value I get is the sys_id.  I cannot get the department name to display or any other field on the Department table to display anything.

Is this possible in a client script?  

1 ACCEPTED SOLUTION

Here's the same script but using your custom field cmn_department.u_department_group:



function onChange(control, oldValue, newValue, isLoading, isTemplate) {
  if (isLoading || newValue === '') {
      return;
  }


  var caller = g_form.getReference('caller_id');
  var dept = caller.department;
  if (dept) {
      var grDept = new GlideRecord('cmn_department');
      if (grDept.get(dept)) {
          confirm(caller.name + ' works at ' + grDept.u_department_group);
      }
  }
}


View solution in original post

16 REPLIES 16

jon421553
Tera Contributor

Great discussion — you’ve definitely hit on a common trap with client-side scripting in ServiceNow. It’s important to know that true “multi-table dot walking” in a client script often doesn’t work as expected because you’re restricted by client-side access and performance with mesolyft .

saiyadavava
Tera Contributor

The issue is that g_form.getReference() is designed to fetch fields only from the directly referenced table, not tables referenced by fields within that table (i.e., it doesn't support dot-walking to a second or third table).

Since the department field on the User (sys_user) table is a reference field pointing to the Department (cmn_department) table, g_form.getReference('caller_id').department only returns the Sys ID of the Department record.

 

Solution :

To achieve true dot-walking across multiple tables in a Client Script, you must use GlideAjax to query the server asynchronously. This is the recommended and performant practice in ServiceNow.

1.Create a Script Include (Server-Side)

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

getDepartmentDetails: function() {
var callerSysId = this.getParameter('sysparm_user_id');
var deptSysId = '';
var deptName = '';
var deptGroup = '';

// 1. Get the User record and the Department Sys ID
var userGR = new GlideRecord('sys_user');
if (userGR.get(callerSysId)) {
deptSysId = userGR.department;
}

// 2. Use the Department Sys ID to get the Department details
if (deptSysId) {
var deptGR = new GlideRecord('cmn_department');
if (deptGR.get(deptSysId)) {
deptName = deptGR.name.toString(); // Name of the department
// Get the custom field value
deptGroup = deptGR.u_department_group.toString();
}
}

// Return a JSON string containing all the required data
return JSON.stringify({
name: deptName,
group: deptGroup
});
},

type: 'CallerLookup'
});

 

2.Change your Client-Script

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading || newValue === '') {
return;
}

// newValue is the sys_id of the new Caller
var callerSysId = newValue;

// Initialize GlideAjax and point it to the Script Include name
var ga = new GlideAjax('CallerLookup');

// Specify the function name in the Script Include to call
ga.addParam('sysparm_name', 'getDepartmentDetails');

// Pass the Caller's Sys ID as a parameter to the server
ga.addParam('sysparm_user_id', callerSysId);

// Execute the call asynchronously
ga.getXML(DepartmentParse);
}

// Callback function to handle the response from the server
function DepartmentParse(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");

// Check if a valid JSON response was returned
if (answer) {
// Parse the JSON string back into a JavaScript object
var deptData = JSON.parse(answer);

// Access the department name and custom field value
var deptName = deptData.name;
var deptGroup = deptData.group;g_form.addInfoMessage('Department Name: ' + deptName);
g_form.addInfoMessage('Department Group (u_department_group): ' + deptGroup);
}
}