Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

GlideAJAX not working for affected CIs list

Jerome MAISETTI
Mega Guru

Hello
I have the following need to have a UI Action on the related list "Affected CIs" to create one change request per selected CI.
I tried to do so with a mix between a UI Script and a GlideAjax, but GlideAjax gives me a Null answer.
Can you help me out please ?

Script Include :

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

    getCiItems: function() {
        var sysIds = this.getParameter('sysparm_sys_ids'); // Expecting a comma-separated list of sys_ids
        var answer = [];
        
        // Debugging: log the sysIds received
        gs.info('Received sysparm_sys_ids: ' + sysIds);

        if (!sysIds) {
            gs.info('No sys_ids provided');
            return JSON.stringify(answer); // Return empty list
        }

        // Split sysIds into an array
        var sysIdList = sysIds.split(',');
        
        // Debugging: log the sysIdList array
        gs.info('sysIdList array: ' + sysIdList.join(','));

        // Ensure sysIdList is not empty
        if (sysIdList.length === 0) {
            gs.info('sysIdList is empty after split');
            return JSON.stringify(answer);
        }

        var taskCiSysId = new GlideRecord('task_ci');
        taskCiSysId.addQuery('sys_id', 'IN', sysIdList); // Use 'IN' operator for list of sys_ids
        taskCiSysId.query();

        // Check if the query returns any results
        if (!taskCiSysId.hasNext()) {
            gs.info('No records found for the provided sys_ids');
        }

        while (taskCiSysId.next()) {
            gs.info('Found CI Item: ' + taskCiSysId.ci_item.sys_id); // Debugging
            answer.push(taskCiSysId.ci_item); // Collect results
        }

        gs.info('Retrieved CI Items: ' + JSON.stringify(answer)); // Debugging
        return JSON.stringify(answer); // Return as JSON string
    },

    type: 'CIRetriever'
});


UI Script :

 

function processInputs() {
    // Validate the change type selection
    var changeType = gel("change_selection").value;
    if (changeType == '') {
        alert('Change Selection cannot be left blank.');
        return; // Exit if no selection
    }

    // Collect the selected "Affected CI" record sys_ids from the related list
    var selectedTaskCIs = g_list.getChecked(); // These are the sys_ids from the task_ci table
    var selectedTaskCiSplit = selectedTaskCIs.split(',');

    // Log the selected task_ci sys_ids for debugging
    //console.log('Selected Task CI sys_ids:', selectedTaskCIs);

    // Ensure you have valid selections
    if (!selectedTaskCIs || selectedTaskCIs.length === 0) {
        alert('No CIs selected.');
        return; // Exit if no CIs are selected
    }

    // Assuming selectedTaskCiSplit is an array of sys_ids
    //var sysIdList = selectedTaskCiSplit.join(','); // Convert array to comma-separated list
    // Assuming selectedTaskCiSplit is an array of sys_ids
	var sysIdList = selectedTaskCiSplit.join(','); // Convert array to comma-separated list
	var ciToProcess = new GlideAjax('CIRetriever');
	alert('List of CIs to Proceed : ' + sysIdList);
	ciToProcess.addParam('sysparm_sys_ids', sysIdList);
	ciToProcess.getXMLAnswer(function(response) {
    var resultList = JSON.parse(response); // Parse the JSON response
	console.log('AJAX call completed'); // Log after AJAX call
    console.log('AJAX Response:', response); // Log the response to check what is received
	alert('Response from AJAX : ' , response);
    alert('Retrieved CI Items: ', resultList); // Debugging

    if (resultList && resultList.length > 0) {
        // Process each CI
        for (var i = 0; i < resultList.length; i++) {
            createChangeRequest(resultList[i], changeType);
            alert('Processed the following CI: ' + resultList[i]);
        }
    } else {
        alert('No CIs retrieved or failed to retrieve CIs.');
    }
	});
    // Fetch the actual CI sys_ids using GlideAjax
    //for (var i = 0; i < selectedTaskCIs.length; i++) {
    //var taskCiSysId = selectedTaskCIs[i]; // This is the sys_id from the task_ci table
    //g_form.addInfoMessage('ID processed : ' + selectedTaskCIs[i]);
    /*var retrieveCi = new GlideRecord('task_ci');
    retrieveCi.addEncodedQuery('sys_idIN' + selectedTaskCIs);
    retrieveCi.query();
    while (retrieveCi.next()) {
        var ciSysId = retreiveCi.ci_item;
        createChangeRequest(ciSysId, changeType);
        g_form.addInfoMessage('Processed the following CI : ' + ciSysId);
	}*/
    //	}

    /*// Use GlideAjax to fetch the actual CI sys_id (ci_item)
    var ajax = new GlideAjax("get_ci_sys_id");
    ajax.addParam("sysparm_name", "get_ci_sys_id");
    ajax.addParam("sysparm_task_ci_id", taskCiSysId);
    ajax.addParam("sysparm_type", changeType);
    
    ajax.getXMLAnswer(function(response) {
        var ciSysId = response;
        
        if (ciSysId && ciSysId.length === 32) {
            createChangeRequest(ciSysId, changeType);
        } else {
            //alert('Failed to retrieve CI sys_id for Task CI: ' + taskCiSysId);
        }
    });*/

    GlideDialogWindow.get().destroy(); // Close the dialog window after processing
    //g_form.addInfoMessage('Splitted value : ' + selectedTaskCiSplit);

}

// Function to create a change request for a given CI sys_id
function createChangeRequest(ciSysId, changeType) {
    var ajax = new GlideAjax("create_new_change_request");
    ajax.addParam("sysparm_name", "change_request");
    ajax.addParam("sysparm_ci_id", ciSysId);
    ajax.addParam("sysparm_type", changeType);
    ajax.getXMLAnswer(function(response) {
        var answer = response;
    });
}

function processCancel() {
    GlideDialogWindow.get().destroy(); // Close the dialog window
}
6 REPLIES 6

Brad Bowman
Kilo Patron
Kilo Patron

Are you getting any of the logs correctly from the SI - is this working to at least receive the list of sys_ids?  You wouldn't use an array in the addQuery, just the original comma-separated list of sys_ids, and when you push a sys_id to an array like you are doing in answer with ci_item, you must force it to a string or you will return a list of the same sys_id.  You want to return the joined array, not attempting to convert the array to a JSON formatted string.

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

    getCiItems: function() {
        var sysIds = this.getParameter('sysparm_sys_ids'); // Expecting a comma-separated list of sys_ids
        var answer = [];
        
        // Debugging: log the sysIds received
        gs.info('Received sysparm_sys_ids: ' + sysIds);

        if (!sysIds) {
            gs.info('No sys_ids provided');
            return JSON.stringify(answer); // Return empty list
        }
       
        var taskCiSysId = new GlideRecord('task_ci');
        taskCiSysId.addQuery('sys_id', 'IN', sysIds); 
        taskCiSysId.query();

        // Check if the query returns any results
        if (!taskCiSysId.hasNext()) {
            gs.info('No records found for the provided sys_ids');
        }

        while (taskCiSysId.next()) {
            gs.info('Found CI Item: ' + taskCiSysId.ci_item.sys_id); // Debugging
            answer.push(taskCiSysId.ci_item.toString()); // Collect results
        }

        gs.info('Retrieved CI Items: ' + answer.join(','); // Debugging
        return answer.join(','); // Return answer array as string
    },

    type: 'CIRetriever'
});

 

Hello
Thanks for your reply.
I indeed receive the list of sys_ids to pass into the AJAX , here in my code :

var sysIdList = selectedTaskCiSplit.join(','); // Convert array to comma-separated list
	var ciToProcess = new GlideAjax('CIRetriever');
	ciToProcess.addParam('sys_ids', sysIdList);
	alert('CI List : ' + sysIdList);

How can I now get the answer from the AJAX and create one change request per CI returned ?
Thanks

In the UI Script I don't understand why you are splitting selectedTaskCIs, only to check that it's not empty (which you can do as a string) then join it.  That's not hurting anything, just unnecessary.  As I said previously, you need to confirm in the Script Include that you are getting the same list of task_ci sys_ids, then make the other changes to the Script Include syntax and logic to return a valid list of CIs.

I now have the return of the sys ids from the GlideAjax, which is good :). Thanks !
I need now to have the change request creation to work , with the following in the UI Script

function processInputs() {
    // Validate the change type selection
    var changeType = gel("change_selection").value;
    if (changeType == '') {
        alert('Change Selection cannot be left blank.');
        return; // Exit if no selection
    }

    // Collect the selected "Affected CI" record sys_ids from the related list
    var selectedTaskCIs = g_list.getChecked(); // These are the sys_ids from the task_ci table
    var selectedTaskCiSplit = selectedTaskCIs.split(',');

    // Log the selected task_ci sys_ids for debugging
    //console.log('Selected Task CI sys_ids:', selectedTaskCIs);

    // Ensure you have valid selections
    if (!selectedTaskCIs || selectedTaskCIs.length === 0) {
        alert('No CIs selected.');
        return; // Exit if no CIs are selected
    }

    // Assuming selectedTaskCiSplit is an array of sys_ids
    //var sysIdList = selectedTaskCiSplit.join(','); // Convert array to comma-separated list
    // Assuming selectedTaskCiSplit is an array of sys_ids
	var sysIdList = selectedTaskCIs; // Convert array to comma-separated list
	var ciToProcess = new GlideAjax('CIRetriever');
	ciToProcess.addParam('sysparm_name', 'getCiItems');
	ciToProcess.addParam('sysparm_sys_ids', sysIdList);
	alert('CI List : ' + sysIdList);
	ciToProcess.getXMLAnswer(function(response) {
		var ciItems = response;
		alert('Retrieved CI Items : ' + ciItems);
		for (var i = 0; i < ciItems; i++) {
			var createChange = new GlideAjax('create_new_change_request');
			createChange.addParam('sysparm_name', 'change_request');
			createChange.addParam('sysparm_ci_id', ciItems[i]);
			createChange.addParam('sysparm_type', changeType);
			createChange.getXMLAnswer(function(changeResponse) {
				alert('Change request created for CI : ' + ciSysId + ' - Response : ' + changeResponse);
			});
		}
	

	

    GlideDialogWindow.get().destroy(); // Close the dialog window after processing
    //g_form.addInfoMessage('Splitted value : ' + selectedTaskCiSplit);

}


With the following script include :

var create_new_change_request = Class.create();
create_new_change_request.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    change_request: function() {
        var ciSysId = this.getParameter('sysparm_ci_id');
        var changeType = this.getParameter('sysparm_type');

        // Validate the ciSysId
        if (!ciSysId || ciSysId.length !== 32) {
            gs.error('Invalid CI sys_id provided: ' + ciSysId);
            return 'Error: Invalid CI sys_id provided';
        }

        // Retrieve the CI record using the sys_id
        var ciRecord = new GlideRecord('cmdb_ci');
        ciRecord.addQuery('sys_id', ciSysId);
        ciRecord.setLimit(1);
        ciRecord.query();
        if (ciRecord.hasNext()) {
            var ciToApply = ciRecord;
        }
        var change = new GlideRecord("change_request");
        change.initialize();
        change.short_description = 'Change Request for CI: ' + ciRecord.getDisplayValue(); // Using CI name
        change.description = 'This change request is related to CI: ' + ciRecord.getDisplayValue();
		change.cmdb_ci = ciToApply.sys_id;
        change.u_change_origin = 'OCD';
        change.contact_type = 'OCD';
        change.u_requester_s_company = '5c9bdd3101f3b800fa5ff1cd4a39695f'; // Adjust based on your requirements
        change.requested_by = gs.getUserID();
        change.cmdb_ci = ciSysId;
        change.type = changeType; // Set the change type
        change.setWorkflow(false); // Adjust if you need workflows
        var changeSysId = change.insert();

		return changeSysId;

       
},

type: 'create_new_change_request'
});


But it doesn't work. Any idea from your point of view ? 🙂
Thanks again for the precious help!