GlideAjax: return multiple values using JSON

When you are in a client script and need to retrieve information at the database level, the best practice is to use GlideAjax. In some cases, you would need to retrieve multiple values. To achieve this, you could do as explained in the wiki : return multiple XML nodes and attributes from the server. But there is a better alternative: return data using JSON . Doing this way, the data sent from the server is better structured and the script is easier to maintain as it is more comprehensible for the developer.

Return an object or array using JSON

Ideally, in order to send multiple values, it would be nice if we could pass objects or arrays from the server to the client. But this is not possible when using GlideAjax. The solution then is to use a JSON object in order to:
– Encode the data from the server into a JSON formatted string
– Retrieve the JSON formatted string from the client and decode it into a javascript object

Below, the detailed steps in both server and client side scripts followed by 3 examples: return a simple object, return a simple array, return an array of objects.

Server side

1. Prepare the data you want to send to the client. Data can be contained in a simple object or an array.
2. Instantiate a JSON object and encode the data to be sent.
3. Return the data. The data sent to the client is in a JSON formatted string.

Client side

4. Retrieve the data
5. Decode the JSON formatted string into an object or array, which contains multiple values.
6. Process the values regarding the business requirements.

Example 1: return a simple object

Data to be returned

{
  "var1":"Hello",
  "var2":"World"
}

Server Side

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

	helloWorld: function() {
		var obj = {};

		obj.var1 = 'Hello';
		obj.var2 = 'World';

		var json = new JSON();
		var data = json.encode(obj);//JSON formatted string

		return data;
	},

	type: 'MyCustomAjax'
});

Client Side

function onLoad() {
	var ga = new GlideAjax('MyCustomAjax');
	ga.addParam('sysparm_name', 'helloWorld');
	ga.getXML(showMessage);
}

function showMessage(response) {
	var answer = response.responseXML.documentElement.getAttribute("answer");
	g_form.addInfoMessage(answer); //JSON String

	answer = answer.evalJSON(); //Transform the JSON string to an object
	g_form.addInfoMessage(answer);

	g_form.addInfoMessage(answer.var1); //Display "Hello"
	g_form.addInfoMessage(answer.var2); //Display "World"
}

Result

GlideAjax - JSON - Exemple 1

 

Example 2: return a simple array

Data to be returned

[
  "Hello",
  "World 2"
]

Server Side

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

	helloWorld2: function() {
		var customArray = ['Hello', 'World 2'];

		var json = new JSON();
		var data = json.encode(customArray); //JSON formatted string

		return data;
	},

	type: 'MyCustomAjax'
});

Client Side

function onLoad() {
	var ga = new GlideAjax('MyCustomAjax');
	ga.addParam('sysparm_name', 'helloWorld2');
	ga.getXML(showMessage2);
}

function showMessage2(response) {
	var answer = response.responseXML.documentElement.getAttribute("answer");
	g_form.addInfoMessage(answer); //JSON String

	answer = answer.evalJSON(); //Transform the JSON string to an object
	g_form.addInfoMessage(answer);

	for( var i=0 ; i < answer.length ; i++) { //Loop into the array
		g_form.addInfoMessage(answer[i]);
	}
}

Result

GlideAjax - JSON - Exemple 2

Example 3: return an array of objects

Data to be returned

[
  {
    "callerName":"Carol Coughlin",
    "number":"INC0000055",
    "shortDescription":"SAP Sales app is not accessible"
  },
  {
    "callerName":"Luke Wilson",
    "number":"INC0000048",
    "shortDescription":"Having problems with Sales Tools performance"
  },
  {
    "callerName":"Joe Employee",
    "number":"INC0000047",
    "shortDescription":"Issue with email"
  }
]

Server Side

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

	threeLastIncidents: function() {
		var incident = new GlideRecord('incident');
		incident.orderByDesc('sys_created_on');
		incident.setLimit(3);
		incident.query();

		var array = [];

		while(incident.next()) {
			var object = {};
			object.number = incident.getDisplayValue('number');
			object.callerName = incident.getDisplayValue('caller_id');
			object.shortDescription = incident.getDisplayValue('short_description');
			array.push(object);
		}

		var json = new JSON();
		var data = json.encode(array); //JSON formatted string

		return data;
	},

	type: 'MyCustomAjax'
});

Client Side

function onLoad() {
	var ga = new GlideAjax('MyCustomAjax');
	ga.addParam('sysparm_name', 'threeLastIncidents');
	ga.getXML(showMessage3);
}

function showMessage3(response) {
	var answer = response.responseXML.documentElement.getAttribute("answer");
	g_form.addInfoMessage(answer); //JSON String

	answer = answer.evalJSON(); //Transform the JSON string to an object
	g_form.addInfoMessage(answer);

	for( var i=0 ; i < answer.length ; i++) { //Loop into the array
		g_form.addInfoMessage(answer[i].number + " - " + answer[i].callerName + " - " + answer[i].shortDescription);
	}
}

Result

GlideAjax - JSON - Exemple 3

mm
Ximizu Huynh is Senior Consultant at Fruition Partners Europe (ex-Aspediens) in Paris. With more than 8 years of experience in IT, he enjoys sharing about all things related to his passion for the web.
Recent Posts
Showing 10 comments
  • Jeff Thurston
    Reply

    You have a typo in your last client side example:

    ga.getXML(showMessage2);

    should probably be

    ga.getXML(showMessage3);

    • mm
      Ximizu Huynh
      Reply

      Thanks Jeff for having spotted this. I have updated the article accordingly.

      Cheers

      Xim

  • Vamsi
    Reply

    Hi Xim,

    This is really cool, thanks for sharing.

  • Ron Legters
    Reply

    Thank you so much for this. I’m glad I finally found this article! One question though – I want to do this synchronously, so users have to wait for the response before continuing. So:
    var ga = new GlideAjax(‘AJAXGetDCSProductCodeChange’);
    ga.addParam(‘sysparm_name’, ‘getDCSProductCode’);
    ga.addParam(‘sysparm_productCode’, newValue);
    ga.getXML(setFields);

    function setFields(response){
    var answer=response.responseXML.documentElement.getAttribute(“answer”);

    becomes
    var ga = new GlideAjax(‘AJAXGetDCSProductCodeChange’);
    ga.addParam(‘sysparm_name’, ‘getDCSProductCode’);
    ga.addParam(‘sysparm_productCode’, newValue);
    ga.getXMLWait();

    var answer=response.responseXML.documentElement.getAttribute(“answer”);
    ?? but then ‘response’ doesn’t appear to have any value. What’s the syntax to do this?

    • mm
      Ximizu Huynh
      Reply

      Thanks for your comment Ron, I’m glad that it helps you.

      Regarding the synchronous Ajax, to retrieve the answer, I believe that the syntax would be:

      var answer = ga.getAnswer()

      instead of

      var answer=response.responseXML.documentElement.getAttribute(“answer”);

      Check the section “2.1.2 Synchronous Glide Ajax” in the wiki
      http://wiki.servicenow.com/index.php?title=GlideAjax#Synchronous_Glide_Ajax

      Kind Regards,

      Xim

      • Ron Legters
        Reply

        Wow. That’s almost embarrassingly easy. 🙂 Thank you again!

  • Jenny
    Reply

    Thanks so much for this one. I just have one question – do you need to always use the for loop in the client side script? As I have to update just the one record and this for loop would check all the returned answer as an array…this is what I’ve written on the client side:

    function checkModel(response) {
    var answer = response.responseXML.documentElement.getAttribute(“answer”);
    answer = answer.evalJSON();
    //set variable value.
    g_form.setValue(‘sw_version’, answer.version);
    g_form.setValue(‘sw_cost’, answer.licenseType);
    g_form.setValue(‘installation_method’, answer.installationMethod);
    var freeWare = answer.freeware;
    if(freeWare == ‘true’){
    g_form.setValue(‘freeware’, ‘Yes’);
    } else{
    g_form.setValue(‘freeware’, ‘No’);
    }
    }

    • mm
      Ximizu Huynh
      Reply

      Hi Jenny, I’m glad it has helped you. Regarding your question, no, we don’t have to always use a loop in the client script. It depends on the requirements. In my first example, I don’t use a loop.

      I don’t know what you put in server side for your example, but the client script seems to be valid. I assume that in the server side you have returned an object with the following attributes: version, licenseType, installationMethod.

  • Abdul Azeez
    Reply

    Hello Ximizu,

    It helps me to understand how to use and call Script Include using Client Script. But i have a small doubt, In the last Script Include you use function name as “threeLastIncidents” and in Client Script you there is no paramater called with name “threeLastIncidents” i can see “ga.addParam(‘sysparm_name’, ‘helloWorld2’);”, i that should be threeLastIncidents in the client script ???

    • mm
      Ximizu Huynh
      Reply

      Thank you Abdul,

      You are right, it was a copy/paste mistake in the last example.

      I have corrected and replaced

      ga.addParam(‘sysparm_name’, ‘helloWord2’);

      by

      ga.addParam(‘sysparm_name’, ‘threeLastIncidents’);

      Regards

Leave a Comment

Start typing and press Enter to search