We've updated the ServiceNow Community Code of Conduct, adding guidelines around AI usage, professionalism, and content violations. Read more

Called Client Script Returning Undefined

Marc D
Tera Expert

Hello, everyone.  I'm having an issue with an implementation of a solution for my client.

 

I have been tasked for a form to compare the company of a user on the form with another company listed on the form itself, and to make certain fields read-only if they are identical. This is in and of itself fairly simple - a GlideAjax call.

However, I have to use this same functionality multiple times over multiple Client Scripts, and to cut down on the same GlideAjax call being written repeatedly, I placed it within a function within a separate Client Script and had my main Client Scripts call this function.

 

This is how it looks:

Script Include:

getUserCompany: function() {
	var userID = this.getParameter('sysparm_userid');

        if (userID != "") {
            var userGr = new GlideRecord("sys_user");
            if (userGr.get(userID)) {
			   var res = userGr.company;
			   return res;
		    }
         }
     return "";
}

 

Callable Client Script:

userCompanyCheck = function() {
    var user = g_form.getValue('form_user');
    var company = g_form.getValue('form_company');

    var userCompany = new GlideAjax('<Script Include Name>');
    userCompany.addParam('sysparm_name', 'getUserCompany');
    userCompany.addParam('sysparm_userid', user);
    userCompany.getXML(compareCompany);

    function compareCompany(response) {
        var answer = response.responseXML.documentElement.getAttribute("answer");
        if (answer != company) {
            return 'false';
        } else {
            return 'true';
        }
    }
};

Main Client Script:

var userHasSameCompany = userCompanyCheck();
if (userHasSameCompany == 'true') {
        g_form.setValue('internal_comparison_flag', 'No');
} else {
        g_form.setValue('internal_comparison_flag', 'Yes');
}

 

But there's an issue with this: in the main Client Script, userHasSameCompany ALWAYS returns "undefined" from userCompanyCheck(), regardless of whether or not it returned "true" or "false", and I have checked - it has reached both.

 

What is the problem with my implementation? Did I do something wrong?

1 ACCEPTED SOLUTION

lauri457
Tera Sage

Your userCompanyCheck does not return anything. compareCompany is an asynchronous callback function so when it is executed the outer function is long gone from the stack and it doesn't matter what you return from it.

 

You'd need to return a promise from your reusable function. 

function onLoad() {
	g_form.userCompanyCheck = function () {
		return new Promise((resolve) => {
			var user = "35826bf03710200044e0bfc8bcbe5d38a";
			var company = "187d13f03710200044e0bfc8bcbe5df2";

			var userCompany = new GlideAjax('Asd');
			userCompany.addParam('sysparm_name', 'getUserCompany');
			userCompany.addParam('sysparm_userid', user);
			userCompany.getXMLAnswer((answer) => resolve(answer === company));
		})
	};
	g_form.userCompanyCheck().then((r) => {
		console.log(r)
	})
}

 

Even if it were synchronous an inner function return value is not automatically returned from the outer function as they don't share execution context

asd = function () {
	function hmm() {
		return 1
	}
	hmm()
}
gs.info(asd())

//*** Script: undefined

 

View solution in original post

7 REPLIES 7

k_lutz
Giga Sage

Hello @Marc D 

 

I think you code just needs a tweak as it sounds a bit like a timing issue because of the overall structure. Can you try something like this for your main script:

 

userCompanyCheck(function(isSameCompany) {
if (isSameCompany) {
g_form.setValue('internal_comparison_flag', 'No');
} else {
g_form.setValue('internal_comparison_flag', 'Yes');
}
});

 

And then in your client script:

 

function userCompanyCheck(done) {
var user = g_form.getValue('form_user');
var company = g_form.getValue('form_company');

var ga = new GlideAjax('<Script Include Name>');
ga.addParam('sysparm_name', 'getUserCompany');
ga.addParam('sysparm_userid', user);

ga.getXMLAnswer(function(answer) {
// answer will be the sys_id of the company reference (usually)
var isSameCompany = (answer === company);
done(isSameCompany);
});
}

 

You will need to provide the name of your script include and make sure it is client callable.

This sounds like it might work, as some of the debugging I have done is suggesting the getXML function isn't being resolved right away, but

EDIT: This post has been edited as the user confused getXMLAnswer with getXMLWait

Hi @Marc D 

 

Can you try something like this?

 

function userCompanyCheck(done) {
var user = g_form.getValue('form_user');
var company = g_form.getValue('form_company');

var ga = new GlideAjax('<Script Include Name>');
ga.addParam('sysparm_name', 'getUserCompany');
ga.addParam('sysparm_userid', user);

ga.getXML(function(response) {
var answer = response.responseXML.documentElement.getAttribute('answer');
done(answer === company); // boolean
});
}

 

 

userCompanyCheck(function(isSameCompany) {
g_form.setValue('internal_comparison_flag', isSameCompany ? 'No' : 'Yes');
});

 

 

Also in your script include you may want to adjust to:

return userGr.getValue('company');

 

Just want to make sure on both sides you are comparing the sys_ids which I think is your plan.

Hello, k_lutz. First off, I would like to apologize for my first response - I had confused getXMLAnswer with getXMLWait - it's the latter that's not supported and doesn't work in Service Portal.

 

That being said, I have tried both implementations you have suggested, the getXMLAnswer and getXML, and neither worked.

 

I would like to make one little correction on my part, however - I am not actually using the internal Company field for this requirement. I am using a custom-defined String field. I only referred to it as Company for privacy reasons. I should have been more forthright.