Need to push array values to List Collector

Pallavi65
Tera Contributor

Hello all,

 

I have a reference variable in a catalog item and a list collector variable.

Reference field type variable: (u_field1)

List collector type variable: (u_field2)

 

Based on reference field selection, its corresponding values has to be populated or shown in list collector for selection.

I have written a script include and Reference qualifier.

But the list e=collector is displaying only one value but not all the related ones. 

I have out log messages and observed, "Array is" log is giving two sys_ids, but why the list collector is displaying only one?

 

My code screenshot:

 
 
 

Script:

var Cat_scripts = Class.create();

Cat_scripts.prototype = {

    initialize: function() {},

    getActiveContracts: function(cn) {

    gs.log("CN is "+cn);

        var ar = [];

        var gr = new GlideRecord('ast_contract');

       

        gr.addQuery('account', cn);

        gr.query();

        while (gr.next()) {

            ar.push(gr.sys_id);

            gs.log("Array is "+ar);

        }

      

        return ar;

       

    },

    type: 'Cat_scripts'

};

 

 
 

 

 

1 ACCEPTED SOLUTION

By the way, the reason its not pushing multiple values is because your array push is incorrect.

Replace:

ar.push(gr.sys_id);

With:

ar.push(gr.sys_id.toString());

View solution in original post

9 REPLIES 9

Hello Pallavi,

 See the explanation given below. I have already provided the root cause in earlier my suggestion. Please mark this as "Helpful" if this helps you.

The  issue here is that gr.sys_id is an object reference, so when you use ar.push(gr.sys_id);, it's storing a reference to the sys_id object in the array instead of the actual sys_id value. Each time gr.next() is called, the gr.sys_id reference updates to the new record's sys_id, but the previous array entries also update since they reference the same object. As a result, only the last sys_id appears in the array when you log it.

When you use gr.sys_id.toString(), however, it converts the sys_id to a string at that moment, capturing the exact value rather than the object reference. This ensures that each entry in the array holds a unique sys_id string.

Mark this as  "Helpful" if it helped you understand the root cause.

hello @Pallavi65 
Basically, that a pre defined function in JavaScript, here simply use to convert other data type content into string type, like date and time fields or like convert references field etc,

Purpose of toString()

  1. Data Type Conversion:

    It converts objects, arrays, or other non-string types into a string format, which is essential for displaying or logging data.
  2. Consistency:

    Ensures that values being concatenated or compared are of the same type (string), preventing potential type errors in expressions.
  3. Readability:

    When debugging or logging, converting values to strings helps provide clearer and more understandable log messages.

Why Use toString()?

When Concatenating: If you are building a string that includes different types (like numbers or objects), using toString() ensures that they are properly formatted as strings.

When Logging: It allows for better log output, making it easier to track the flow and values in your scripts.

When Returning Values: In functions or methods that expect a string, using toString() ensures you meet the expected return type.

If this is helpful for you, please mark it as helpful and don’t forget to leave your comments!
REGARDS
Muhammad Talha

AishwaryaS1
Kilo Sage

@Pallavi65 @AnirudhKumar will it be worked for the change request form.

I have a requirement: 

We have a custom locations field of type List Collector. 

Also have a dropdown field "What type of location is affected" with choices:

  1. Enterprise Wide
  2. Region
  3. Country
  4. Select Locations
  • When Region=True display a list collector field titled "Regions" which only shows the regions on the cmn_location table (Mandatory)
  • When Country=true display a list collector field titled "Countries" which only shows the countries on the cmn_location table (Mandatory)
  • When Select Locations=True display a list collector field titled "Locations" of all of the locations on the cmn_location table (Please modify the attributes of the list collector so that siteID is displayed in the first column) (Mandatory)
Aishwarya Shelake

Hello Aishwarya,

 You’ll need to set up dynamic display of fields based on the "What type of location is affected" dropdown value and configure List Collector filters for Regions, Countries, and Locations.
I have have come up with following list of actions:

1. Create the Fields:
Add a List Collector field for each selection in the dropdown:
Regions (filters cmn_location table by regions)
Countries (filters cmn_location table by countries)
Locations (shows all locations with Site ID as the first column)
Set each List Collector field to Mandatory but Hidden initially.

2. Client Script:
An onChange Client Script for the dropdown field ("What type of location is affected").
This script will dynamically show the appropriate List Collector based on the selected value.

Example of the client script:

function onChange(control, oldValue, newValue, isLoading) {
       if (isLoading || newValue === '') {
           return;
       }
       
       // Hide all List Collector fields by default
       g_form.setDisplay('regions', false);
       g_form.setDisplay('countries', false);
       g_form.setDisplay('locations', false);
       
       // Set Mandatory and display fields based on dropdown selection
       if (newValue === 'Region') {
           g_form.setDisplay('regions', true);
           g_form.setMandatory('regions', true);
       } else if (newValue === 'Country') {
           g_form.setDisplay('countries', true);
           g_form.setMandatory('countries', true);
       } else if (newValue === 'Select Locations') {
           g_form.setDisplay('locations', true);
           g_form.setMandatory('locations', true);
       }
   }

3. Filtering List collections (i.e. Ref qualifying)

Add filters for each List Collector by setting up Reference Qualifiers:
Regions List Collector: Add a reference qualifier to show only Region -type entries.
Countries List Collector: Filter to show only Country-type entries.
Locations List Collector: Show all locations.

4. Add Custom Attributes for Site ID in Locations:
Go to the List Collector's dictionary entry for Locations.
In the Attributes field, add:

ref_auto_completer=AJAXTableCompleter,ref_ac_columns=siteID


This setting will display the Site ID as the first column in the Locations List Collector.

With this setup:
Selecting "Region" will display a filtered Regions List Collector.
Selecting "Country" will show a Countries List Collector.
Selecting "Select Locations" will display a Locations List Collector with Site ID as the first column.

Please mark response as "Helpfuls" if it really helped you.

maheshkhatal
Mega Sage

Hello,

 

The issue here is that gr.sys_id is an object reference, so when you use ar.push(gr.sys_id);, it's storing a reference to the sys_id object in the array instead of the actual sys_id value. Each time gr.next() is called, the gr.sys_id reference updates to the new record's sys_id, but the previous array entries also update since they reference the same object. As a result, only the last sys_id appears in the array when you log it.

When you use gr.sys_id.toString(), however, it converts the sys_id to a string at that moment, capturing the exact value rather than the object reference. This ensures that each entry in the array holds a unique sys_id string.

To resolve this, you should use gr.sys_id.toString() in your ar.push() line, see changes to the code below:

  

 

Script:

var Cat_scripts = Class.create();

Cat_scripts.prototype = {

    initialize: function() {},

    getActiveContracts: function(cn) {

    gs.log("CN is "+cn);

        var ar = [];

        var gr = new GlideRecord('ast_contract');

       

        gr.addQuery('account', cn);

        gr.query();

        while (gr.next()) {
        // ar.push(gr.sys_id.toString());  // Convert to string to avoid reference issue
            ar.push(gr.sys_id.toString());

            gs.log("Array is "+ar);

        }

      

        return ar;

       

    },

    type: 'Cat_scripts'

};