Array is being populated with identical values when iterating through table

Oliver Anderson
Kilo Sage

I've written a script that will part of a Mail Script. My goal is to get all of the application names in the cmdb_ci_business_app table where the specific user is the Business Owner (owned_by) on that application.

 

For example, in my cmdb_ci_business_app table these are two records where I am the Business Owner:

OliverAnderson_0-1699034326102.png

 

In my script, I am querying GlideRecord('cmdb_ci_business_app') and adding the name of each application where the Business Owner's email matches a pre-defined email variable. However, when I run the script, it is gathering the correct number of records owned by me, but the name of the elements in the array are all 'SNOW Edge Browser Plug-In' (the last record in the table).

EDIT: If I change the email variable to a different user's email address, the array is being populated with the correct number of elements, but they are all 'SNOW Edge Browser Plug-In' as well.

 

What am I doing wrong?

 

Script:

 

var applications = [];    //Create array 'applications' to store all applications for each Business Owner
var email = 'oanderson@everwisecu.com';
gs.log(email);

    var gr = new GlideRecord('cmdb_ci_business_app');    //Create GlideRecord object 'user' as sys_user table
    gr.query();    
    while (gr.next()) {    //Iterate through cmdb_ci_business_app table
        var businessOwner = gr.owned_by.getRefRecord();    //Create object 'owner' and store current reference in owned_by
        if (businessOwner.email == email) {    //If current Business Owner's sys_id on current application matches current sys_id in 'businessOwners' array, add the current application name to 'applications'
            applications.push(gr.name);   
        }
    }
    
    applications.forEach(displayApplications);    //Call function 'displayApplications()' for each application in 'applications'
	
	function displayApplications(value) {
		gs.log(value);    //Print current application in 'applications'
		//template.print('</br>' + value);
	}

 

 

Output:

OliverAnderson_1-1699034558663.png

 

2 ACCEPTED SOLUTIONS

Brad Bowman
Kilo Patron
Kilo Patron

Try forcing the value to a string (even though it already should be) when you push it into an array.  This is necessary with sys_id type fields as otherwise it is pushing the memory location, which is always the same.  Stranger things have worked:

            applications.push(gr.name.toString());   

View solution in original post

OlaN
Giga Sage
Giga Sage

Hi,

This is the classic Pass-By-Reference issue .

When sending data to the array in this manner, the data is evaluated from memory, instead of giving the actual value.

By utilizing the getValue() method you make sure this is avoided. Make it a habit to use it.

 

Providing a simple example you can test in a scripts background to show the difference in how the value is being stored.

var inc = new GlideRecord('incident');
inc.setLimit(3);
inc.query();
var arrayStuff = [];
while (inc.next()){
    arrayStuff.push(inc.number);
    gs.info(inc.getValue('number'));
}
gs.info('array: ' + arrayStuff.join(','));

View solution in original post

4 REPLIES 4

Brad Bowman
Kilo Patron
Kilo Patron

Try forcing the value to a string (even though it already should be) when you push it into an array.  This is necessary with sys_id type fields as otherwise it is pushing the memory location, which is always the same.  Stranger things have worked:

            applications.push(gr.name.toString());   

Very odd. That worked.

OliverAnderson_0-1699036557644.png

 

Out of curiosity, would you be able to explain why this issue doesn't occur when I don't hard-code the email variable? Based on your answer, I'm guessing it's something along the lines of comparing the attributes of an object versus a sys_id type field as you mentioned?

 

Script:

var businessOwners = [];    //Create array 'businessOwners' to store all Business Owners in cmdb_ci_business_app
var arrayUtil = new ArrayUtil();    //Initialize ArrayUtil script includes

var gr = new GlideRecord('cmdb_ci_business_app');    //Create GlideRecord object 'gr' as cmdb_ci_business_app table
gr.query();
while (gr.next()) {    //Iterate through cmdb_ci_business_app table
    var businessOwner = gr.owned_by.getRefRecord();    //Create object 'businessOwner' and store current reference in owned_by
    if (!arrayUtil.contains(businessOwners, businessOwner.sys_id)) {    //If array 'businessOwners' does not already contain current 'businessOwner' sys_id, add the current 'businessOwner' sys_id to 'businessOwners'
        businessOwners.push(businessOwner.sys_id);
    }
}

businessOwners.forEach(getApplications);    //Call function 'getApplications()' for each sys_id in 'businessOwners'

function getApplications(value) {    
    var applications = [];    //Create array 'applications' to store all applications for each Business Owner

    var user = new GlideRecord('sys_user');    //Create GlideRecord object 'user' as sys_user table
    user.get(value);    //Get record on sys_user table with current sys_id
    gs.log(user.name);

    gr.query();    
    while (gr.next()) {    //Iterate through cmdb_ci_business_app table
        var businessOwner = gr.owned_by.getRefRecord();    //Create object 'owner' and store current reference in owned_by
        if (businessOwner.sys_id == value) {    //If current Business Owner's sys_id on current application matches current sys_id in 'businessOwners' array, add the current application name to 'applications'
            applications.push('    ' + gr.name);   
        }
    }
    
    applications.forEach(displayApplications);    //Call function 'displayApplications()' for each application in 'applications'
}

function displayApplications(value) {
    gs.log(value);    //Print current application in 'applications'
}

 

Output:

OliverAnderson_1-1699036684301.png

 

OlaN
Giga Sage
Giga Sage

Hi,

This is the classic Pass-By-Reference issue .

When sending data to the array in this manner, the data is evaluated from memory, instead of giving the actual value.

By utilizing the getValue() method you make sure this is avoided. Make it a habit to use it.

 

Providing a simple example you can test in a scripts background to show the difference in how the value is being stored.

var inc = new GlideRecord('incident');
inc.setLimit(3);
inc.query();
var arrayStuff = [];
while (inc.next()){
    arrayStuff.push(inc.number);
    gs.info(inc.getValue('number'));
}
gs.info('array: ' + arrayStuff.join(','));

This worked as well. Thanks for the read as well!