Jake Gillespie
Mega Guru

In an earlier post, I shared my advice on using client-server communications in ServiceNow in order to improve IT Service Desk efficiency. To recap, I focused on the fact that there are various options available for handling communications between the client and the server when requesting related information, and in the process covered Client Scripts, the GlideForm API and GlideAjax specifically.

I recently received an excellent question about this post from a reader, and I wanted to take the opportunity to share both the question and answer with everyone since I think it hits on a common theme (and one which is becoming more common due to the increased number of Scoped Applications being developed).

The question came from someone who was trying to call a Script Include (extending AbstractAjaxProcessor aka GlideAjax) created in a privately scoped application from an onChange Client Script of the same Application Scope. However, they kept getting a blank value and suspected the issue was related to Application Scope.

What could be the cause of this? And how could they (or anyone else who finds themselves in this position) go about remedying the situation? Here's my take on the problem:

There are many reasons why GlideAjax calls fail to return the value you're expecting, and therefore many places to review when debugging. However, in this particular case, the most likely issue was a missing "global" Namespace prefix in the Class definition of the extended GlideAjax Script Include. Here's a walk-through of how to convert the example used in my earlier blog post (which was in the global scope) to a privately scoped Script Include definition:

Global Scope Definition:

1.png

Private Scope Definition:

2.png

The subtle difference is the "global" Namespace prefix before the "AbstractAjaxProcessor" reference in the definition for extending the GlideAjax Class. The reason that this is important is because privately scoped scripts need to know if the Class they're calling is from a different Application Scope (e.g. global), and this is identified by using a Namespace. Whenever you reference scripts from a different scope, you need to prefix them with the Namespace to which they belong. If you don't do this, it is assumed to be in the same Application Scope and will result in an error (assuming there is no Class defined by that name in the same scope).

In this example, the privately scoped Class (ConfigurationItemAjax) needs to access a Class in the global scope (AbstractAjaxProcessor). Similarly, if the dependant Class was defined in another Application Scope (instead of global), it would need to be prefixed with something like "x_abc_myappname" (whatever the Namespace is for the other Application Scope).

If the above suggestion does not resolve the issue of returning a blank value, I recommend doing some further debugging:

  1. 1. Confirm that you have the correct function names referenced (e.g. the Client Script function calls the right Class name and function name).
  2. 2. Check the developer/JavaScript console in your browser for any errors. If you have a "POST [instance URL] 404 (not found)" error, then it means you are not receiving a server response, and this could be because the Class name supplied is not an Active GlideAjax extended Script Include. Check that the Script Include is "Client Callable" and "Active," then check the spelling of the Script Include name against the Client Script call.
  3. 3. If you're not getting the above POST error and you're simply getting a null value from the response, you'll need to debug the response. The way I do this is to add a debugging line into your callback function where you reference "response" etc., and copy this reference to the g_scratchpad object (e.g g_scratchpad.response = response.responseXML;). This will allow you to access the responseXML object in your developer console after you attempt the GlideAjax call. Often times you can navigate this object and determine what actually came back from the server. If the "result" tag or "answer" attribute are missing, then you should check your Script Include function, as it's likely not returning the correct values.
  4. 4. Building on step 3 above, another tip is hardcoding a return value from your Script Include function (this will rule out errors in your logic to return a specific value).

So there you have it, my tips for debugging GlideAjax issues. And remember, when working with scripts from a Private Scope Application, pay attention to Namespace prefixes.

For more information on the topics covered in this article, please see the following pages:

NOTE: MY POSTINGS REFLECT MY OWN VIEWS AND DO NOT NECESSARILY REPRESENT THE VIEWS OF MY EMPLOYER.

3 Comments