Help

Re: How to use output.set correctly

Solved
Jump to Solution
4110 3
cancel
Showing results for 
Search instead for 
Did you mean: 
Emily_Montgomer
5 - Automation Enthusiast
5 - Automation Enthusiast

I'm trying to use a script in an automation to filter specific records from a view and then include those records in the next step of the automation (which would be inserting them into an email to send).

I can get the script to successfully find and filter the records needed, and it looks like I need to use output.set to export the info back to the automation, but I'm having issues figuring out how to do so.

When I run the script below, I'm getting the following error: 

TypeError: Invalid arguments passed to output.set(key, value): • value[0] should be a JSON-serializable type, not an object
 
Anyone know how to fix what I have for the output.set part or any guidance at all? Thanks!
const table = base.getTable("Sessions");
let view = table.getView("Sorted Active Coaching Sessions");
let inputConfig = input.config();
let CoachingAssignment = inputConfig.CoachingAssignment;

const fieldName = "CAMatch"
const queryResult = await view.selectRecordsAsync({fields: [fieldName]})
const MatchingSessions = queryResult.records.filter(record => (
record.getCellValueAsString(fieldName) == CoachingAssignment
))

console.log(MatchingSessions)

output.set("session", queryResult.records.filter(record => (
record.getCellValueAsString(fieldName) == CoachingAssignment
)))
1 Solution

Accepted Solutions

Actually, you can have both!

Here's a script that provides both an array of record IDs and a separate array of the values of that field.
It's worth noting that this version will also filter out all records where the StartTime field returns empty.

const table = base.getTable('Sessions');
let view = table.getView('Sorted Active Coaching Sessions');
let inputConfig = input.config();
let CoachingAssignment = inputConfig.CoachingAssignment;

const fields = ['CAMatch', 'StartTime'];

let records = await view.selectRecordsAsync({ fields: fields }).then(query => query.records);

let matchingSessions = records
    .filter(record => record.getCellValueAsString(fields[0]) == CoachingAssignment && record.getCellValue(fields[1]));

let recordIds = matchingSessions?.map(record => record.id);
let dateValues = matchingSessions
    ?.map(record => record.getCellValue(fields[1]))
    .sort();


output.set('Matching Records', recordIds);
output.set('Session Dates', dateValues);

If you just want to output only the values from the StartTime field, you could use this version.
This version also does not filter out records where that field is empty.

const table = base.getTable('Sessions');
let view = table.getView('Sorted Active Coaching Sessions');
let inputConfig = input.config();
let CoachingAssignment = inputConfig.CoachingAssignment;

const fields = ['CAMatch', 'StartTime'];

let records = await view.selectRecordsAsync({ fields: fields }).then(query => query.records);
let matchingSessionDates = records
    .filter(record => record.getCellValueAsString(fields[0]) == CoachingAssignment)
    ?.map(record => record.getCellValue(fields[1]))
    .sort();

output.set('Session Dates', matchingSessionDates);

 This version will filter records where the StartTime field is empty:

const table = base.getTable('Sessions');
let view = table.getView('Sorted Active Coaching Sessions');
let inputConfig = input.config();
let CoachingAssignment = inputConfig.CoachingAssignment;

const fields = ['CAMatch', 'StartTime'];

let records = await view.selectRecordsAsync({ fields: fields }).then(query => query.records);
let matchingSessionDates = records
    .filter(record => record.getCellValueAsString(fields[0]) == CoachingAssignment && record.getCellValue(fields[1]))
    ?.map(record => record.getCellValue(fields[1]))
    .sort();

output.set('Session Dates', matchingSessionDates);

 

See Solution in Thread

8 Replies 8

Hey @Emily_Montgomer!

Give this a whirl and let me know if it resolves your problem or not:

const { CoachingAssignment } = input.config();

const table = base.getTable("Sessions");
const view = table.getView("Sorted Active Coaching Sessions");
const fields = ['CAMatch'];

let sessionRecords = await view.selectRecordsAsync({ fields: fields }).then(query => query.records);

const filterSession = (sessionRecord) => {
    let fieldName = fields[0];
    return sessionRecord.getCellValueAsString(fieldName) === CoachingAssignment;
};

sessionRecords = sessionRecords.filter(filterSession);

output.set('session', sessionRecords);

Thanks for taking the time! This didn't throw an error, but the filter isn't returning any values at all now. It was working successfully with what I had just not outputting. Any idea?

I'm curious if your use of the loose equality operator to evaluate whether the field value equals the CoachingAssignment constant is what was allowing your filter implementation to evaluate to true.

Give this tweaked version of your script a whirl:

const table = base.getTable('Sessions');
let view = table.getView('Sorted Active Coaching Sessions');
let inputConfig = input.config();
let CoachingAssignment = inputConfig.CoachingAssignment;

const fieldName = 'CAMatch';
let records = await view.selectRecordsAsync({ fields: [fieldName] }).then(query => query.records);
let matchingSessions = records.filter(record => record.getCellValueAsString(fieldName) == CoachingAssignment);

output.set('session', matchingSessions);

This gives me the same error I initially had "TypeError: Invalid arguments passed to output.set(key, value): • value[0] should be a JSON-serializable type, not an object".

I'm guessing I just can't output an entire record; can I output just a particular field from the filtered records? 

Ultimately, what I'm trying to do is isolate a list of sessions for a certain user, and I want the sessions to be ordered by StartTime. I can get those sessions from the automation itself, but they aren't sorted, so I'm trying to add a script step instead to get them from the table (from a view where they're already sorted). And, I can figure that part out, but what I can't figure out is how to get them back to the automation. 

Ah.
I'm a dummy and didn't sit to properly consider the data type you were passing to the output.set() function.
The result of your filtering will return you with an array of AirtableRecord types.

The correct solution would be to export an array of the record ids that you filtered.
You can then feed that array of ids to another automation action, as you were intending.

Here's the updated script:

 

const table = base.getTable('Sessions');
let view = table.getView('Sorted Active Coaching Sessions');
let inputConfig = input.config();
let CoachingAssignment = inputConfig.CoachingAssignment;

const fieldName = 'CAMatch';
let records = await view.selectRecordsAsync({ fields: [fieldName] }).then(query => query.records);
let matchingSessions = records
    .filter(record => record.getCellValueAsString(fieldName) == CoachingAssignment)
    ?.map(record => record.id);



output.set('session', matchingSessions);

 

Here, matchingSessions goes from a AirtableRecord[] type, to being a string[] | undefined type.

Thanks! That works, and I'm able to at least see a list of the session IDs in the automation's next step now. If I want to get a field from those records called 'StartTime' instead of just the IDs, do you know how I would format that?

Actually, you can have both!

Here's a script that provides both an array of record IDs and a separate array of the values of that field.
It's worth noting that this version will also filter out all records where the StartTime field returns empty.

const table = base.getTable('Sessions');
let view = table.getView('Sorted Active Coaching Sessions');
let inputConfig = input.config();
let CoachingAssignment = inputConfig.CoachingAssignment;

const fields = ['CAMatch', 'StartTime'];

let records = await view.selectRecordsAsync({ fields: fields }).then(query => query.records);

let matchingSessions = records
    .filter(record => record.getCellValueAsString(fields[0]) == CoachingAssignment && record.getCellValue(fields[1]));

let recordIds = matchingSessions?.map(record => record.id);
let dateValues = matchingSessions
    ?.map(record => record.getCellValue(fields[1]))
    .sort();


output.set('Matching Records', recordIds);
output.set('Session Dates', dateValues);

If you just want to output only the values from the StartTime field, you could use this version.
This version also does not filter out records where that field is empty.

const table = base.getTable('Sessions');
let view = table.getView('Sorted Active Coaching Sessions');
let inputConfig = input.config();
let CoachingAssignment = inputConfig.CoachingAssignment;

const fields = ['CAMatch', 'StartTime'];

let records = await view.selectRecordsAsync({ fields: fields }).then(query => query.records);
let matchingSessionDates = records
    .filter(record => record.getCellValueAsString(fields[0]) == CoachingAssignment)
    ?.map(record => record.getCellValue(fields[1]))
    .sort();

output.set('Session Dates', matchingSessionDates);

 This version will filter records where the StartTime field is empty:

const table = base.getTable('Sessions');
let view = table.getView('Sorted Active Coaching Sessions');
let inputConfig = input.config();
let CoachingAssignment = inputConfig.CoachingAssignment;

const fields = ['CAMatch', 'StartTime'];

let records = await view.selectRecordsAsync({ fields: fields }).then(query => query.records);
let matchingSessionDates = records
    .filter(record => record.getCellValueAsString(fields[0]) == CoachingAssignment && record.getCellValue(fields[1]))
    ?.map(record => record.getCellValue(fields[1]))
    .sort();

output.set('Session Dates', matchingSessionDates);

 

THANKS!!!! 🎉 I appreciate your time. This works perfectly.