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!