The CreatorCon Call for Content is officially open! Get started here.

Assistance Needed: Issue with Client Script Populating Reference Type Variable

Erica2
Tera Contributor

Hello,

I have a client script that calls Script Includes to populate a "Reference" type variable. This is working fine using it in an Alert, but I'm having trouble getting the code to work in reference variable.

 

Could someone please review the code and suggest any fixes? Thank you!

 

 

Erica2_0-1741125167965.png

 

CLIENT SCRIPT:

function onCondition() {
    var requestor = g_form.getValue('who_is_this_request_for');
    var ga = new GlideAjax('getUnitManager');
    ga.addParam('sysparm_name', 'managerName');
    ga.addParam('sysparm_requestor', requestor);

    ga.getXMLAnswer(getResponse);

    function getResponse(response) {
        g_form.setValue('current_unit_manager', response);  // current_unit_manager is a reference type variable
}

 

SCRIPT INCLUDES:

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

    managerName: function() {
        var manager = '';
        var requestedFor = this.getParameter('sysparm_requestor');
        var gr = new GlideRecord('sys_user');
        gr.get(requestedFor);  // Ensure the 'requestedFor' parameter is valid
        if (gr.isValidRecord()) {
            manager = gr.manager;
            if (manager) {
                return this.getManagerTitle(manager); // Call the function to get the manager's title
            }
        }
        return 'No manager found for user'; // More informative message if no manager is found
    },

    getManagerTitle: function(mgr) {
        var usr = new GlideRecord('sys_user');
        usr.get('sys_id', mgr);
        if (usr.isValidRecord()) {
            // Check if both "Group" or "Unit" are in the title
            var isGroupAndUnit = usr.title && usr.title.indexOf("Group") != -1 || usr.title.indexOf("Unit") != -1;
            if (isGroupAndUnit) {
                // If both "Group" or "Unit" are in the title, return the name of the manager
                return usr.name; 
            } else {
                // If the manager's title does not contain both "Group" or "Unit", return the next level's manager
                if (usr.manager) {
                    return usr.manager.getDisplayValue();  // Recursive call to find the next manager
                }
                return 'No higher-level manager found'; // Return this if no manager exists at a higher level
            }
        }
        return 'No manager found'; // Return if no valid user record is found
    },

    type: 'getUnitManager'
});

 

1 ACCEPTED SOLUTION

Nick Parsons
Mega Sage

You need to set the sys_id of your manager when setting a reference field, not the name/title. 

 

eg:

managerSysId: function() {
        var manager = '';
        var requestedFor = this.getParameter('sysparm_requestor');
        var gr = new GlideRecord('sys_user');
        if(gr.get(requestedFor) && gr.isValidRecord()) {  // Ensure the 'requestedFor' parameter is valid
            manager = gr.manager;
            if (manager) {
                return manager.sys_id.toString();
            }
        }
 },

Then in your client script, call this new method and check if it returns a sys_id or not:

function onCondition() {
    var requestor = g_form.getValue('who_is_this_request_for');
    var ga = new GlideAjax('getUnitManager');
    ga.addParam('sysparm_name', 'managerSysId');
    ga.addParam('sysparm_requestor', requestor);

    ga.getXMLAnswer(getResponse);

    function getResponse(response) {
        if(response) {
          g_form.setValue('current_unit_manager', response);  // current_unit_manager is a reference type variable
        }
   }
}

Of course, you can also return an object from your script to include things like the manager name and a server-side error message along with the sys_id so that you can use the second argument to g_form.setValue() and show an error message from the server-side if you wish.

View solution in original post

9 REPLIES 9

moeiz
Tera Contributor

Your client script and Script Include logic are mostly correct, but there are a few issues that could cause problems when setting the reference variable.

  1. Client Script Issue: response is not returning the sys_id

    • The response from getXMLAnswer() is a string, but g_form.setValue() for a reference variable expects a sys_id, not a display name.
    • Your Script Include is returning the manager’s display name instead of their sys_id.
  2. Ensure getXMLAnswer() Handles Null or Undefined Responses

    • If no manager is found, your script should handle empty responses.
  3. Ensure managerName() Retrieves the Correct sys_id

    • The manager field in sys_user is a reference field, so gr.manager is a reference object, not a string.

Mark my answer as helpful, if it did any.

Nick Parsons
Mega Sage

You need to set the sys_id of your manager when setting a reference field, not the name/title. 

 

eg:

managerSysId: function() {
        var manager = '';
        var requestedFor = this.getParameter('sysparm_requestor');
        var gr = new GlideRecord('sys_user');
        if(gr.get(requestedFor) && gr.isValidRecord()) {  // Ensure the 'requestedFor' parameter is valid
            manager = gr.manager;
            if (manager) {
                return manager.sys_id.toString();
            }
        }
 },

Then in your client script, call this new method and check if it returns a sys_id or not:

function onCondition() {
    var requestor = g_form.getValue('who_is_this_request_for');
    var ga = new GlideAjax('getUnitManager');
    ga.addParam('sysparm_name', 'managerSysId');
    ga.addParam('sysparm_requestor', requestor);

    ga.getXMLAnswer(getResponse);

    function getResponse(response) {
        if(response) {
          g_form.setValue('current_unit_manager', response);  // current_unit_manager is a reference type variable
        }
   }
}

Of course, you can also return an object from your script to include things like the manager name and a server-side error message along with the sys_id so that you can use the second argument to g_form.setValue() and show an error message from the server-side if you wish.

Thank you so much for your help, @Nick Parsons 

The code successfully returned the manager's name when I passed in the manager's sys ID. However, I seem to have made an error somewhere in the code.

 

There are two functions, managerSysId and getManagerTitle. The getManagerTitle function is supposed to check if the word "Group" appears anywhere in the title. If it does, it should return the manager's name.

 

If "Group" isn't in the title, it should return the next level's manager instead.

When you get a chance, could you take a look at where I might have gone wrong? I'd appreciate your insights so I can learn from the mistake.

 

 

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

   managerSysId: function() {
        var manager = '';
        var requestedFor = this.getParameter('sysparm_requestor');
        var gr = new GlideRecord('sys_user');
        gr.get(requestedFor);  
        if (gr.isValidRecord()) {
            manager = gr.manager;
            if (manager) {
                // Call the function to get the manager's title
                return this.getManagerTitle(manager.sys_id.toString()); 
            }
        }
        return 'No manager found for user'; 
    },

    getManagerTitle: function(mgr) {
        var usr = new GlideRecord('sys_user');
        usr.get('sys_id', mgr);
        if (usr.isValidRecord()) {
            // Check if "Group" exists in the title anywhere
            var isGroup = usr.title && usr.title.indexOf("Group") != -1;  // Check if title contains "Group"
            if (isGroup) {
                // If the title contains "Group", return the name of the group manager
                return usr.name.sys_id.toString(); 
            } else {
                // If the manager's title does not contain "Group", return the next level's manager
                if (usr.manager) {
                   
					return usr.manager.sys_id.toString(); 
					
				}
                return 'No higher-level manager found'; // Return this if no manager exists at a higher level
            }
        }
        return 'No manager found';
    },

 

Hi, so first issue is that you're trying to read the sys_id from the name string field, which won't work, instead you need to just read the sys_id from the user:

 

return usr.sys_id.toString();  // instead of: return usr.name.sys_id.toString(); 

 

While this may not be an issue, if the user's title is not a group, you're only looking one level higher, but that may also not be a group either... one way to fix that is to make your function recursive:

 

return this.getManagerTitle(usr.manager.sys_id);  // instead of: return usr.manager.sys_id.toString(); 

 

 Lastly, the function that returns the sys_id (managerSysId) should return consistent data. At the moment you're returning a sys_id sometimes, and then other times you're returning an error message in a string. Your front-end client side code won't know what to do with the error message string as currently it just uses the output to set the value of your reference field (so it assumes it's a sys_id). Ideally, you should return an object if you want an error message, something like:
{sys_id: <id if can be found, null if otherwise>, error: <error message, if there is one, empty string if all good>}
That way your return value from the function is consistent and your front-end client side code can then use this object to determine if there are any errors to report, or if everything worked all OK. But error handling is a bit out of this question's scope anyway.