Going inside loop so many times

indrajeetma
Tera Guru
(function executeRule(current, previous /*null when async*/) {
    var acc = current.u_account.toString();
    var exp = new GlideDate(current.u_expiration_date);
    var loc = current.u_location;
    var listt = current.u_list_product_family;
    gs.log("indraa " + listt);
    var array = listt.split(",");
    gs.log("indraa " + array + " " + array.length);
    var length = array.length;
    for(var i =0 ; i<length; i++)
    {
        gs.log("hi");
        var flag = false;
        var gr = new GlideRecord('u_test');
        gr.addQuery('u_account', acc);
        gr.addQuery('u_expiration_date', exp);
        gr.addQuery('u_location', loc);
        gr.addQuery('u_product_fam', array[i]);
        gr.setLimit(1);
        gr.query();
        if(gr.next())
        {
            flag = true;
           

        }
        gs.log("indra " + flag);
        if(flag == false)
        {
            var insert1 = new GlideRecord('u_test');
            insert1.initialize();
            insert1.u_account = acc;
            insert1.u_location = loc;
            insert1.u_expiration_date = exp;
            insert1.u_product_fam = array[i];
            insert1.u_list_product_family = listt;
            insert1.insert();
        }
    }



    //current.setAbortAction(true);
})(current, previous);
5 REPLIES 5

Community Alums
Not applicable

Hi @indrajeetma ,

 try this code 

(function executeRule(current, previous /*null when async*/) {
    // Get values from the current record
    var acc = current.u_account.toString();
    var exp = new GlideDate(current.u_expiration_date);
    var loc = current.u_location;
    var listt = current.u_list_product_family;
    var array = listt.split(",");
    gs.log("Product Families: " + array);

    // Create a set to track existing product families
    var existingProductFamilies = new Set();

    // Query 'u_test' table to fetch existing records that match account, location, and expiration date
    var gr = new GlideRecord('u_test');
    gr.addQuery('u_account', acc);
    gr.addQuery('u_expiration_date', exp);
    gr.addQuery('u_location', loc);
    gr.query();
    while (gr.next()) {
        existingProductFamilies.add(gr.u_product_fam.toString());
    }

    // Iterate through the array and check if each product family already exists
    for (var i = 0; i < array.length; i++) {
        var productFamily = array[i];
        gs.log("Processing Product Family: " + productFamily);

        if (!existingProductFamilies.has(productFamily)) {
            // Insert a new record if the product family does not exist
            var insert1 = new GlideRecord('u_test');
            insert1.initialize();
            insert1.u_account = acc;
            insert1.u_location = loc;
            insert1.u_expiration_date = exp;
            insert1.u_product_fam = productFamily;
            insert1.u_list_product_family = listt;
            insert1.insert();
            gs.log("Inserted new record for Product Family: " + productFamily);
        } else {
            gs.log("Product Family already exists: " + productFamily);
        }
    }
})(current, previous);

Mark Manders
Mega Patron

This could come from numerous points in your script and since we only get your script without anything else, a lot of guessing and assumptions can proof to not resolve anything, but here's a go:

  • current.u_list_product_family could contain values that keep inserting operations
  • var array = listt.split(",") could have empty values (or trailing values), creating empty elements
  • gr.query() loop relies on dynamic data. If your query doesn't limit the results, it can be processing the same record over and over again
  • The flag variable should be scoped and reset to prevent unintended behavior
  • validate that your new GlideDate(current.u_experation_date) is properly formatted

Any doubts on the above can be checked by adding logging to the script to see what it is actually doing.

 

You haven't stated what the script is for and what it is supposed to do (maybe it would even be better as a flow?).

 

Try what it does when you put it like this:

(function executeRule(current, previous /*null when async*/) {
    var acc = current.u_account.toString();
    var exp = new GlideDate(current.u_expiration_date); // Ensure date format compatibility
    var loc = current.u_location;
    var listt = current.u_list_product_family;
    var array = listt.split(",").filter(function(item) {
        return item.trim() !== "";  // Remove empty or invalid items
    });

    gs.info("Processing account: " + acc + ", location: " + loc + ", expiration date: " + exp.getDisplayValue());
    gs.info("Product families: " + array);

    for (var i = 0; i < array.length; i++) {
        gs.info("Processing product family: " + array[i] + " at index " + i);

        var gr = new GlideRecord('u_test');
        gr.addQuery('u_account', acc);
        gr.addQuery('u_expiration_date', exp.getDisplayValue());
        gr.addQuery('u_location', loc);
        gr.addQuery('u_product_fam', array[i]);
        gr.setLimit(1);
        gr.query();

        if (!gr.hasNext()) {
            gs.info("Inserting new record for product family: " + array[i]);
            var insert1 = new GlideRecord('u_test');
            insert1.initialize();
            insert1.u_account = acc;
            insert1.u_location = loc;
            insert1.u_expiration_date = exp;
            insert1.u_product_fam = array[i];
            insert1.u_list_product_family = listt;
            insert1.insert();
        }
    }
})(current, previous);

Please mark any helpful or correct solutions as such. That helps others find their solutions.
Mark

Juhi Poddar
Kilo Patron

Hello @indrajeetma 

Try this:

(function executeRule(current, previous /*null when async*/) {
    // Retrieve values from the current record
    var acc = current.u_account.toString();
    var exp = current.u_expiration_date; // No need to create a GlideDate object, as GlideRecord handles date fields directly
    var loc = current.u_location;
    var listt = current.u_list_product_family;

    gs.log("Processing product family list: " + listt);

    // Split the list into an array
    var array = listt.split(",");
    var length = array.length;

    gs.log("Array of product families: " + array + ", Length: " + length);

    // Loop through the array and process each product family
    for (var i = 0; i < length; i++) {
        var productFamily = array[i].trim(); // Trim spaces for clean comparison

        gs.log("Processing product family: " + productFamily);

        // Initialize a GlideRecord for the 'u_test' table
        var gr = new GlideRecord('u_test');
        gr.addQuery('u_account', acc);
        gr.addQuery('u_expiration_date', exp);
        gr.addQuery('u_location', loc);
        gr.addQuery('u_product_fam', productFamily);
        gr.setLimit(1);
        gr.query();

        if (!gr.next()) {
            // If no matching record is found, insert a new one
            gs.log("No record found, creating a new one for product family: " + productFamily);

            var newRecord = new GlideRecord('u_test');
            newRecord.initialize();
            newRecord.u_account = acc;
            newRecord.u_location = loc;
            newRecord.u_expiration_date = exp;
            newRecord.u_product_fam = productFamily;
            newRecord.u_list_product_family = listt;
            newRecord.insert();
        } else {
            gs.log("Record already exists for product family: " + productFamily);
        }
    }
})(current, previous);
  • Removed the flag conditions as it can be handled directly with !
  • Added log at multiple place to debug

Hope this helps!

 

"If you found my answer helpful, please like and mark it as an "accepted solution". It helps future readers to locate the solution easily and supports the community!"

 

Thank You
Juhi Poddar

samikshajai
Tera Contributor
We are trying to convert below client script into business rule.
Our previous approach was to create a on-submit client script and give a call to script include but as these are not compatible with each other so we are trying to achieve the same with business rule.
Problems we are facing:
1.With before insert business rule,more than 180 records are inserting.
2.With after business rule,script showing error message for all the records even for non-duplicates and also creating empty records.
 
function onSubmit() {

    if (g_form.isNewRecord()) {
        var ListProductFamily = [];

        var gr = new GlideRecord('u_trial_account');
        gr.initialize();
        ListProductFamily = g_form.getValue('u_list_product_family');
        var arrayListProductFamily = ListProductFamily.split(',');
        var n = 0;
        var sysIdInsert = [];
        var sizeInsert;

        arrayListProductFamily.forEach(function(i) {

            if (checkDuplicates(i)) {

                gr.u_account = g_form.getValue('u_account');
                gr.u_location = g_form.getValue('u_location');
  
                gr.u_expiration_date = g_form.getValue('u_expiration_date');
                gr.u_list_product_family = g_form.getValue('u_list_product_family');
                gr.u_product_family = i;

                sysIdInsert.push(gr.insert());
            } else {
                g_form.addInfoMessage('Duplicate record not inserted');
                g_form.submitted = false;
               
               
            }
            n++;
        });

        if (g_form.getActionName() == 'sysverb_insert') {


            location.href = g_form.getTableName() + '_list.do';
            g_form.submitted = false;
            return false;

        } else {

            location.href = g_form.getTableName() + '.do?sys_id=' + sysIdInsert[0];
            g_form.submitted = false;
            return false;
        }
    } else if (!checkDuplicates(g_form.getValue('u_product_family'))) {
        g_form.addInfoMessage('Duplicate record not inserted');
        g_form.submitted = false;
        return false;
    }
   
   

    function checkDuplicates(productFamily) {
        gr = new GlideRecord('u_trial_account');
        gr.addQuery('u_account', g_form.getValue('u_account'));
        gr.addQuery('u_location', g_form.getValue('u_location'));
        gr.addQuery('u_expiration_date', g_form.getValue('u_expiration_date'));
        gr.addQuery('u_product_family', productFamily);
        gr.query();

        if (gr.next()) {
            alert(gr.u_account);
            return false;
        } else {
            return true;
        }

    }
}