Querying a Decision Table from a Catalog Client Script

Kelly Logan
Kilo Sage

The goal is to have a catalog item that maps a generic type of computer to the current default product model for that type (Desktop, Laptop 14", Laptop 15"). I would like to decouple the mapping from the code so that users can update the mapping (twice a year or so) without having to re-code the script for the catalog item variable. 

 

My current plan is to use a decision table, but I am having issues implementing this in that the Ajax call is returning a null value. When I test the basic script it works fine, but the Ajax call is failing. 

 

Here is the script include I wrote to call with Ajax:

var AjaxDecisionTableUtil = Class.create();
AjaxDecisionTableUtil.prototype =
    Object.extendsObject(
        AbstractAjaxProcessor, {
            // Uses the "Default computer HW Model" Decision table
            // Input: Form factor (string)
            // Output: Hardware Model reference.
            ComputerModel: function() {
				var inputs = gs.nil(this.getParameter('inputs')) ? null : this.getParameter('inputs');
                var dt = new sn_dt.DecisionTableAPI();
                var decisionTableSysID = gs.getProperty('com.glide.decision_table.computer_model');
                var response = dt.getDecision(decisionTableSysID, inputs);
                return response;
            }
        }
    );

And here is the catalog client script: 

KellyLogan_0-1731620374234.png

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

    try {
        g_form.addInfoMessage('Form factor: ' + newValue);
        var inputs = new Object();
        inputs['u_form_factor'] = newValue;
        var ga = new GlideAjax('global.AjaxDecisionTableUtil');
        ga.addParam('sysparm_name', 'ComputerModel'); // ComputerModel is the script include method 
        ga.addParam('inputs', inputs); // input map 
        ga.getXMLWait();
        var response = ga.getAnswer();
        if (response) {
            var model = response.result_elements.u_model;
            g_form.addInfoMessage('Model: ' + model);
            g_form.setValue('v_hardware_model', model);

        } else {
            g_form.addInfoMessage('Response null.');
        }
    } catch (message) {
        g_form.addErrorMessage(message);
    }
    //  
}

When I change the Form factor value, the messages displayed are:

KellyLogan_1-1731620483281.png

If there's an easier way to do this (other than creating ACL to try and use a flow action), or a way to debug this, I am open to options. I'm hoping there is something simple I'm missing in the Ajax call or my script include. Note that since this running in real-time to update a field value, I used the getXMLWait() method. Also, the Decision table is returning a model - is this an issue? Since the response itself is showing as null, I'm assuming it's not a reference issue, but maybe my check is incorrect?

 

 

 

 

 

2 REPLIES 2

Tai Vu
Kilo Patron
Kilo Patron

Hi @Kelly Logan 

It looks like the issue might be due to passing an object between the Script Include and Client Script without converting it to a string. Could you try updating your script as shown below?

Client Script:

try {
	var inputs = new Object();
	inputs['u_form_factor'] = newValue;
	var ga = new GlideAjax('AjaxDecisionTableUtil');
	ga.addParam('sysparm_name', 'getHardwareModel');
	ga.addParam('inputs', JSON.stringify(inputs)); //stringify inputs
	ga.getXMLAnswer(function(response) { //change to getXMLAnswer
		if (response) {
			var model = response;
			g_form.addInfoMessage('Model: ' + model);
			g_form.setValue('hardware_model', model);
		} else {
			g_form.addInfoMessage('Response null.');
		}
	});

} catch (message) {
	g_form.addErrorMessage(message);
}

 

Script Include:

getHardwareModel: function() {
	var inputs = this.getParameter('inputs');
	inputs = JSON.parse(inputs);
	var dt = new sn_dt.DecisionTableAPI();
	var decisionTableSysID = gs.getProperty('com.glide.decision_table.computer_model');
	var response = dt.getDecision(decisionTableSysID, inputs);
	return response.result_elements.u_model; //return the hardware model's sys_id only since we don't need the entire response object in this case
},

 

Let me know if it works for you.

 

Cheers,

Tai Vu

Kelly Logan
Kilo Sage

Note: The customer doesn't want to spend more time on this so I have hardcoded the hardware model sys_ids into the Select Box variable, then added a Catalog Data Lookup Definition to match the sys_id back to the hardware model table and set that into the Reference variable:
Form factor variable (Select Box)

KellyLogan_0-1731944574624.png

Catalog Data Lookup Definition

KellyLogan_1-1731944757901.png

 

This is working very nicely. (Note: Because the lookup only runs on non-null input, I also added a UI action to clear the model field when the form factor variable is set to "-None-".)

 

What would be nicer though is if the form factor variable, that maps a generic name to a specific hardware model, could still use the decoupled Decision Table entries, with the input column as the label and the output as the variable. If anyone has played with the decision tables enough to know the background structure and could tell me if this is possible, or if there is an easier way to do this (like a way in asset management to declare a default computer type), please let me know.

(Also, if you can actually help fix the Ajax call, I'm still a bit curious about that.)