Help

Custom Script within Automation

Topic Labels: Scripting
Solved
Jump to Solution
2339 4
cancel
Showing results for 
Search instead for 
Did you mean: 
ss22
5 - Automation Enthusiast
5 - Automation Enthusiast

I'm trying to build an automation that uses a custom script to determine whether all necessary leads have been assigned to a record within the base. The teamsNeeded field (multiple select field type) determines the teams that need leads on the record. Each team then has a lead field (single select field type) where the lead is selected. If "Comms" and "KM" are selected in the teamsNeeded field then the "Comms Lead" and "KM Lead" field need to have a selection/not be empty.

I have limited scripting experience but have been able to build the one below. The issue is that it is outputting 'All Leads Assigned' even when leads are missing. The console log for teamsNeeded shows that all teams are being captured - the log for the example with "Comms" and "KM" in the teamsNeeded field reads "teamsNeeded (2) ["Comms", "KM"].

Is there something I am missing that is causing the output to always be 'All Leads Assigned' instead of 'Leads Missing' when leads are missing?

 

 

// Get values from the automation's input
let teamsNeeded = input.config().teamsNeeded || [];

console.log('teamsNeeded', teamsNeeded)

// Define mapping of teams to lead fields
const teamLeadFields = {
    'CM': 'CM Lead',
    'Comms': 'Comms Lead',
    'LXD': 'LXD Lead',
    'Training Delivery': 'TD Lead',
    'KM': 'KM Lead',
    'Quality': 'Quality Lead',
    'Engagement': 'Engagement Lead', 
    'MLCE': 'MLCE Lead'
};

// Check if required lead fields are filled
let allLeadsAssigned = true;
for (const team of teamsNeeded) {
    const leadField = teamLeadFields[team];

    // Check if input.record is defined 
    if (input.record && !input.record.getCellValue(leadField)) { 
        console.log(`Lead field '${leadField}' is empty for team '${team}'`); // Add this line
        allLeadsAssigned = false;
        break; // No need to check further
    } else if (input.record) {
        console.log(`Lead field '${leadField}' is filled for team '${team}'`); // Add this line
    }
}

// Output for the automation to use
let outputMessage = allLeadsAssigned ? 'All Leads Assigned' : 'Leads Missing';
output.set('allLeadsAssigned', outputMessage);

 

 

 

 

1 Solution

Accepted Solutions
Alexey_Gusev
13 - Mars
13 - Mars

Hi, 
if you really want to

 

 

// Check if input.record is defined 

 

 

 put 

console.log(input.record)  somewhere - you'll see it is undefined
in order to get record, you need to query it
you can add record ID to the input parameters
then 

 

const {teamsNeeded,ID}=input.config()
let record=await base.getTable('YOUR_TABLE_NAME').selectRecordAsync(ID)

then continue your script, put 'record' instead of 'input.record. in loop
if linter annoys you that 'record could be null', you can use:
 if (record && record.getCellValue('Field')    - exactly what you did
 if (record?.getCellValue('Field'))  - this is shorter form of higher
 if(!record) throw new Error ('Record not defined')  - put it somewhere before the if(record  clause, maybe even outside the loop, but i'm not sure, testing needed. So-called 'guard clause' describes 'pessimistic' scenario at first, then work with others. Usually it helps to avoid complex nested IFs. 


I would recommend to do it and test and then check about ES6 way

this part

let allLeadsAssigned = true;
for (const team of teamsNeeded) {
    const leadField = teamLeadFields[team];

    // Check if input.record is defined 
    if (input.record && !input.record.getCellValue(leadField)) { 
        console.log(`Lead field '${leadField}' is empty for team '${team}'`); // Add this line
        allLeadsAssigned = false;
        break; // No need to check further
    } else if (input.record) {
        console.log(`Lead field '${leadField}' is filled for team '${team}'`); // Add this line
    }
}


if you OK with the fact that console.log('Lead field '${leadField}' is empty/filled ') can be omitted,
all this block can be substituted by 

let allLeadsAssigned = teamsNeeded.every(team => record.getCellValue(teamLeadFields[team]))


I suggest to not use 'short' way until you check 'long'  and sure to understand how 'short' works

And by the way, if your multiselect options doesn't include each other (like, for example. 'inactive'   includes ' active'), you can do all this by a formula, without script. That's the first real world scenario I've seen here to use XOR logical function.



 

See Solution in Thread

4 Replies 4

You haven't shown what the inputs or the outputs to the script are, so it is hard to tell what is going on. For example, are you getting any output in the console?

My guess from reading the script is that your script does not output anything to the console, because input.record is undefined and thus nothing in your if statements ever executes.

Can you share more about your coding experience and what resources you used to write this script?

Alexey_Gusev
13 - Mars
13 - Mars

Hi, 
if you really want to

 

 

// Check if input.record is defined 

 

 

 put 

console.log(input.record)  somewhere - you'll see it is undefined
in order to get record, you need to query it
you can add record ID to the input parameters
then 

 

const {teamsNeeded,ID}=input.config()
let record=await base.getTable('YOUR_TABLE_NAME').selectRecordAsync(ID)

then continue your script, put 'record' instead of 'input.record. in loop
if linter annoys you that 'record could be null', you can use:
 if (record && record.getCellValue('Field')    - exactly what you did
 if (record?.getCellValue('Field'))  - this is shorter form of higher
 if(!record) throw new Error ('Record not defined')  - put it somewhere before the if(record  clause, maybe even outside the loop, but i'm not sure, testing needed. So-called 'guard clause' describes 'pessimistic' scenario at first, then work with others. Usually it helps to avoid complex nested IFs. 


I would recommend to do it and test and then check about ES6 way

this part

let allLeadsAssigned = true;
for (const team of teamsNeeded) {
    const leadField = teamLeadFields[team];

    // Check if input.record is defined 
    if (input.record && !input.record.getCellValue(leadField)) { 
        console.log(`Lead field '${leadField}' is empty for team '${team}'`); // Add this line
        allLeadsAssigned = false;
        break; // No need to check further
    } else if (input.record) {
        console.log(`Lead field '${leadField}' is filled for team '${team}'`); // Add this line
    }
}


if you OK with the fact that console.log('Lead field '${leadField}' is empty/filled ') can be omitted,
all this block can be substituted by 

let allLeadsAssigned = teamsNeeded.every(team => record.getCellValue(teamLeadFields[team]))


I suggest to not use 'short' way until you check 'long'  and sure to understand how 'short' works

And by the way, if your multiselect options doesn't include each other (like, for example. 'inactive'   includes ' active'), you can do all this by a formula, without script. That's the first real world scenario I've seen here to use XOR logical function.



 

ss22
5 - Automation Enthusiast
5 - Automation Enthusiast

Apologies - I did not specify in my original post that I did have an input for teamsNeeded so the output in the console was including the teams needed as expected. I was able to resolve this issue with @Alexey_Gusev solution below. Thank you!

ss22
5 - Automation Enthusiast
5 - Automation Enthusiast

Thank you @Alexey_Gusev! Adding ID as an input and adjusting to the 'short' way for allLeadsAssigned worked.