Comparing two Arrays (GlideRecords) and remove duplicates for a Reference qualifier.

Wesley Breshear
Tera Expert

Hello,

I am have built a form to Add/Remove users from ServiceNow Groups, I now want to limit the ability for the user to be able to select a group that he/she is already a member of.  So I am using a Reference qualifier on the catalog form field to call a Script Include. [ javascript: new getSNGroupsFiltered().getGroupsFilter(); ]

I may gone about this the wrong way so I am looking for help with the current script or if I should do it a different way.  I using two Glide Records, one for my 'active' groups 'array1' (sys_user_group) and one for the groups the user is a member of 'array2'.  I have tried to compare the two and have my 'array2' (sys_user_grmember) values be removed from my larger 'array1'.  So 'array3' should be all my 'active' Groups minus any groups that the user is a member of [1-2=3].

Currently, I am only returning one selectable group in 'array3', the very first value of array1'.  I also referenced this article to attempt to compare the two arrays.  https://community.servicenow.com/community?id=community_question&sys_id=5f5fb2a9db58dbc01dcaf3231f9619b6&view_source=searchResult

Any help is much appreciated.

var getSNGroupsFiltered = Class.create();
getSNGroupsFiltered.prototype = {
	getGroupsFilter: function() {
		var array1 = []; // group_array
		var getGroups = new GlideRecord('sys_user_group');
		getGroups.addActiveQuery();  //getGroups.addQuery('active', true);
		getGroups.addQuery('u_assign_work', true);
		getGroups.addQuery('type', '!=', 'e04c61210f85c700f3a05d78a1050e66');  // Group (Parent)
		getGroups.addQuery('type', '!=', '7ad5de00db2ed7002911e525ca9619ec');  // Locked Membership
		getGroups.addQuery('type', '!=', '7b55f402db406f001bd3c170ba96198c');  // read-only
		getGroups.query();
		while(getGroups.next()) {
			array1.push(getGroups.sys_id + '');  //group_array
		}
		gs.log("WLB - Array1 = " + array1);
		//return 'sys_idIN' + array1.join();  //group_array
		
		var user = current.variables.u_user_name;
		var array2 = [];  //userGroup_array
		var getUserGroups = new GlideRecord('sys_user_grmember');
		getUserGroups.addQuery('user', user);
		getUserGroups.query();
		while(getUserGroups.next()) {
			array2.push(getUserGroups.group + '');  //userGroup_array
		}
		gs.log("WLB - Array2 = " + array2);
		
		var array3 = [];
		for(var i = 0; i < array1.length; i++) {
			if(array2.indexOf(array1[i]) == -1) {
				array3.push(array1[i]);
			}
			gs.log("WLB - Array3 = " + array3);
			return 'sys_idIN' + array3.join();
		}
	},
	type: 'getSNGroupsFiltered'
};

Thank you,

-Wesley

1 ACCEPTED SOLUTION

Pradeep Sharma
ServiceNow Employee
ServiceNow Employee

Hello Wesley,

 

Try with the below updated script.

 

var getSNGroupsFiltered = Class.create();
getSNGroupsFiltered.prototype = {
getGroupsFilter: function() {
var gp = ' ';
var user = current.variables.u_user_name;
var array1 = []; // group_array
var getGroups = new GlideRecord('sys_user_grmember');
getGroups.addQuery('group.active', true);
getGroups.addQuery('group.u_assign_work', true);
getGroups.addQuery('group.type', '!=', 'e04c61210f85c700f3a05d78a1050e66'); // Group (Parent)
getGroups.addQuery('group.type', '!=', '7ad5de00db2ed7002911e525ca9619ec'); // Locked Membership
getGroups.addQuery('group.type', '!=', '7b55f402db406f001bd3c170ba96198c'); // read-only
getGroups.addQuery('user', '!=', user);
getGroups.query();
while(getGroups.next()) {
if (gp.length > 0) {
//build a comma separated string of groups if there is more than one
gp += (',' + getGroups.group);
}
else {
gp = getGroups.group;
}
}
// return Groups where assigned to is in those groups we use IN for lists
return 'sys_idIN' + gp;
},
type: 'getSNGroupsFiltered'
};

 

Thanks,

Pradeep Sharma

View solution in original post

6 REPLIES 6

Hi Pradeep,

This could also work without building a second query/expression.  The following works by returning the filter right after your query on the user's existing membership:

(just call as 'javascript:availableGroupsFilter(current.variables.u_user_name)' in the refQual)

function availableGroupsFilter(userID){
	var grMemberOf = new GlideRecord('sys_user_grmember');
	grMemberOf.addQuery('user', userID);
	grMemberOf.query();
	var membership = [];
	while(grMemberOf.next()){
		gs.addInfoMessage("Member of:\t" + grMemberOf.group.sys_id);// For Testing Only
		membership.push(grMemberOf.group.sys_id.toString());
	}
	var restrictions = 'active=true^type!=7ad5de00db2ed7002911e525ca9619ec';//For Example, can add other criteria here.
	gs.addInfoMessage("Group NOT IN " + membership.join());// For Testing Only
	return restrictions + '^sys_idNOT IN' + membership.join(",");
}

 

Do you know of any disadvantage to using the "NOT IN" statement within the refQual itself, vs. using it in a second step of your filter function?

 

Thanks,

-Brian

 

Wesley Breshear
Tera Expert

Brilliant!  Thanks!