When a record has multiple date fields, sometimes you’d like to know which date is the earliest.
In this example base, each record is a social post that has different live dates for different channels. I’d like to know the earliest live date across all three channels. I could do this in a formula, but the ‘LIVE DATE’ field is also used by other teams, so I’d rather calculate the date with the below script.
Script Code
// ?? ?Add all the date fields you need here ? ??
let fields = ['Instagram Date','IG Stories Date','Facebook Date','LIVE DATE']
// Let Airtable know which table and views records you want to use
let table = base.getTable("Content");
let view = table.getView('All');
let query = await view.selectRecordsAsync({fields:fields});
let records = query.records;
// Find the Earliest Date
let dates = records.map( c => fields.map( x => (c.getCellValue(x) != null && x != 'LIVE DATE') ? Date.parse(c.getCellValue(x)) : null).filter(x => x));
let minRaw = dates.map( c => c.reduce((acc,cur) => Math.min(acc,cur)));
let min = minRaw.map( c => new Date(c).toISOString())
let update = min.map( (c,i) => ({id:records[i].id,fields:{
'LIVE DATE': c
}}));
/*
Use this function to perform 'Update', 'Create', or 'Delete'
async actions on batches of records that could potentially
more than 50 records.
::PARAMETERS::
action = string; one of 3 values:
- 'Update' to call table.updateRecordsAsync()
- 'Create' to call table.createRecordsAsync()
- 'Delete' to call table.deleteRecordsAsync()
table = Table; the table the action will be performed in
records = Array; the records to perform the action on
- Ensure the record objects inside the array are
formatted properly for the action you wish to
perform
::RETURNS::
recordsActedOn = integer, array of recordId's, or null;
- Update Success: integer; the number of records processed by the function
- Delete Success: integer; the number of records processed by the function
- Create Success: array; the id strings of records created by the function
- Failure: null;
*/
async function batchAnd(action, table, records) {
let recordsActedOn;
switch (action) {
case 'Update':
recordsActedOn = records.length;
while (records.length > 0) {
await table.updateRecordsAsync(records.slice(0, 50));
records = records.slice(50);
};
break;
case 'Create':
recordsActedOn = [];
while (records.length > 0) {
let recordIds = await table.createRecordsAsync(records.slice(0, 50));
recordsActedOn.push(...recordIds)
records = records.slice(50);
};
break;
case 'Delete':
recordsActedOn = records.length;
while (records.length > 0) {
await table.deleteRecordsAsync(records.slice(0, 50));
records = records.slice(50);
}
break;
default:
output.markdown(`**Please use either 'Update', 'Create', or 'Delete' as the "action" parameter for the "batchAnd()" function.**`);
recordsActedOn = null;
}
return recordsActedOn;
}
// Update the records
await batchAnd('Update',table,update)