Service Portal Client Script - Async wait for functions to complete before submitting

Vegard S
Kilo Sage

I have a catalog item where I want to chain several functions together and wait for all of them to complete before submitting. 

I followed this KB: https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB0779964

But I'm running into a few issues. Firstly, if my complete code looks like this:

function onSubmit() {
	if (g_scratchpad.isFormValid)
		return true;

	var actionName = g_form.getActionName();
	doAsyncTask (function() {
		g_scratchpad.isFormValid = true;
		g_form.submit(actionName);
	});
	
	return false;
}

I get an error message saying "doAsyncTask" is undefined.

If I edit doAsyncTask to a variable instead, it doesn't run at all. I could verify this by adding a console.log

var syncTask = function() {
	g_scratchpad.isFormValid = true;
	g_form.submit(actionName);
};

In essense, what I'm really after is chaining several functions together, and be sure they are finished before the form is submitted. My basic code structure looks like this:

function onSubmit() {
    if (g_scratchpad.isFormValid)
        return true;

    chechUserData();
    checkGroupData();
    printStuff();

    return false;
}

function checkUserData() {
    g_form.setValue('someVariable', 'some value');
}


function checkGroupData(){
    var grMembership = new GlideAjax('REUtils');
    grMembership.addParam('sysparm_name', 'checkGroupNamesForUserNoCatItems');
    grMembership.addParam('sysparm_userId', g_form.getValue('edit_user_ref_user'));
    grMembership.getXML(parseMembershipResponse);
}

function parseMembershipResponse(response){
    var answer =  response.responseXML.documentElement.getAttribute('answer');
    var json = JSON.parse(answer);
    g_form.setValue('somevariable', json);
}

function printStuff() {
    //Stitch together all responses to a single string and add to g_form variable
    g_scratchpad.isFormValid = true;
}

I do realize my bottom code is incomplete, but the idea was that I only want to set g_scratchpad.isFormValid at the end, to make sure the form is only submitted once everything is complete. 


1 ACCEPTED SOLUTION

Sebastian R_
Kilo Sage

The "doAsyncTask" is not a function you should call it´s more the hint that you do your async stuff. As an example with one one your functions

function onSubmit() {
	if (g_scratchpad.isFormValid)
		return true;

	var actionName = g_form.getActionName();
	
	checkGroupData();

	return false;
}

function checkGroupData(){
    var grMembership = new GlideAjax('REUtils');
    grMembership.addParam('sysparm_name', 'checkGroupNamesForUserNoCatItems');
    grMembership.addParam('sysparm_userId', g_form.getValue('edit_user_ref_user'));
    grMembership.getXML(parseMembershipResponse);
}

function parseMembershipResponse(response){
    var answer =  response.responseXML.documentElement.getAttribute('answer');
    var json = JSON.parse(answer);
    g_form.setValue('somevariable', json);
	
	g_scratchpad.isFormValid = true;
		g_form.submit(actionName);
}

If you have multiple different ajax calls you could either put them together in one call or chain them (e.g. calling the next ajax call in parsemembershipResponse).

If you want to use the ajax calls in parallel you probably need more attributes in g_scratchpad (e.g. ajaxRunning, groupAjaxFinished, userAjaxFinished) to handle the logic.

View solution in original post

2 REPLIES 2

Sebastian R_
Kilo Sage

The "doAsyncTask" is not a function you should call it´s more the hint that you do your async stuff. As an example with one one your functions

function onSubmit() {
	if (g_scratchpad.isFormValid)
		return true;

	var actionName = g_form.getActionName();
	
	checkGroupData();

	return false;
}

function checkGroupData(){
    var grMembership = new GlideAjax('REUtils');
    grMembership.addParam('sysparm_name', 'checkGroupNamesForUserNoCatItems');
    grMembership.addParam('sysparm_userId', g_form.getValue('edit_user_ref_user'));
    grMembership.getXML(parseMembershipResponse);
}

function parseMembershipResponse(response){
    var answer =  response.responseXML.documentElement.getAttribute('answer');
    var json = JSON.parse(answer);
    g_form.setValue('somevariable', json);
	
	g_scratchpad.isFormValid = true;
		g_form.submit(actionName);
}

If you have multiple different ajax calls you could either put them together in one call or chain them (e.g. calling the next ajax call in parsemembershipResponse).

If you want to use the ajax calls in parallel you probably need more attributes in g_scratchpad (e.g. ajaxRunning, groupAjaxFinished, userAjaxFinished) to handle the logic.

I don't have multiple ajax calls, but when it made me realize that I can just put the ajax call to the scratchpad onLoad instead of checking it on submit. Then I can just compare the new values to the scratchpad values when submitting 🙂