Aug 14, 2021 07:34 AM
I am new to Scripting and need assistance with modifying the following Airtable Script, which is working well with the Base that I am creating. Unfortunately, I do not want the script to request user input for the number records to create; instead, I want it to use the number that is contained with in a field in the GOODS IN table. Can anyone help please?
let settings = input.config({
title: 'Create child linked records',
description: `For a record in a "parent" table, this script will create some
number of “child” records in another table, where each “child” references the “parent”
through a Linked Record field.`,
items: [
input.config.table('parentTable', { label: 'GOODS IN' }),
input.config.table('childTable', { label: 'LOTS IN' }),
input.config.field('linkField', {
parentTable: 'childTable',
label: 'Linked record field',
}),
],
});
async function createChildrenLinkedRecords() {
let { parentTable, childTable, linkField } = settings;
if (
linkField.type !== 'multipleRecordLinks' ||
linkField.options.linkedTableId !== parentTable.id
) {
output.text('Linked record field must be of type linked record to parent table.');
return;
}
// Airtable limits batch operations to 50 records or fewer.
let maxRecordsPerCall = 50;
let parentRecord = await input.recordAsync('Parent record', parentTable);
let newRecordCount = parseInt(await input.textAsync('Number of records to create'), 10);
let newRecords = [];
// Part 1: Prepare the new records
for (let index = 0; index < newRecordCount; index += 1) {
newRecords.push({
fields: {
[linkField.id]: [{ id: parentRecord.id }],
},
});
}
// Part 2: Perform the record creation operations in batches
while (newRecords.length > 0) {
await childTable.createRecordsAsync(newRecords.slice(0, maxRecordsPerCall));
newRecords = newRecords.slice(maxRecordsPerCall);
}
output.text('Done');
}
await createChildrenLinkedRecords();
Solved! Go to Solution.
Aug 14, 2021 08:57 AM
Try this, replacing “FIELD NAME” with the name of the field containing the number you want to use:
let newRecordCount = parentRecord.getCellValue("FIELD NAME");
NOTE: this will only work as written if the field is a number field. If it’s another field type, try this variant instead:
let newRecordCount = parseInt(parentRecord.getCellValueAsString("FIELD NAME"));
Aug 14, 2021 08:57 AM
Try this, replacing “FIELD NAME” with the name of the field containing the number you want to use:
let newRecordCount = parentRecord.getCellValue("FIELD NAME");
NOTE: this will only work as written if the field is a number field. If it’s another field type, try this variant instead:
let newRecordCount = parseInt(parentRecord.getCellValueAsString("FIELD NAME"));
Aug 15, 2021 01:23 AM
Hi Justin,
Thank you; that worked. I did however run into trouble when I tried to run the revised script with an Automation, so I tried to hard code the settings (as follows):
let parentTable = base.getTable (‘GOODS IN’);
let childTable = base.getTable (‘LOTS IN’);
let linkField = (“GI Reference”);
async function createChildrenLinkedRecords() {
if (
linkField.type !== 'multipleRecordLinks' ||
linkField.options.linkedTableId !== parentTable.id
)
// Airtable limits batch operations to 50 records or fewer.
let maxRecordsPerCall = 50;
let parentRecord = await input.recordAsync('Parent record', parentTable);
let newRecordCount = parentRecord.getCellValue("Number of Lots");
let newRecords = [];
// Part 1: Prepare the new records
for (let index = 0; index < newRecordCount; index += 1) {
newRecords.push({
fields: {
[linkField.id]: [{ id: parentRecord.id }],
},
});
}
// Part 2: Perform the record creation operations in batches
while (newRecords.length > 0) {
await childTable.createRecordsAsync(newRecords.slice(0, maxRecordsPerCall));
newRecords = newRecords.slice(maxRecordsPerCall);
}
output.text('Done');
}
await createChildrenLinkedRecords();
This resulted in an ERROR MESSAGE
Syntax error:
Lexical declaration cannot appear in a single-statement context [script.js:13:5]
Can you help please.
Aug 15, 2021 09:06 AM
There are a few issues that I can see.
getTable
is a method (a type of function) on base
. Similar to writing functions in an Airtable formula field, there cannot be a space between the function name and its opening parenthesis. Those two lines should look like this:
let parentTable = base.getTable('GOODS IN');
let childTable = base.getTable('LOTS IN');
In the next line, the linkField
variable needs to be assigned an actual field instance, but you’re assigning it a string representing the name of the field. It should look like this:
let linkField = childTable.getField("GI Reference");
I also noticed that you removed the feedback to the user—the output.text
portion not far below that field assignment—if linkField
isn’t chosen correctly, but you left the if
statement before it. The two are connected, so you can’t remove the result without also removing the condition. Be sure to remove these lines while you’re editing the script:
if (
linkField.type !== 'multipleRecordLinks' ||
linkField.options.linkedTableId !== parentTable.id
)
That should take care of most (if not all) of the remaining issues, but those are just the things that I saw when quickly skimming what you pasted.
Speaking of pasting code in the forum, it’s strongly recommended to use the preformatted text option, which will properly format all of the code. As it stands, only some of the script lines are formatting cleanly because their indentation happens to trigger single-line formatting. To mark your script as preformatted text in a post, select the script lines, then click this icon in the post editor toolbar: </>
Aug 15, 2021 08:05 PM
Just some additional details:
let parentRecord = await input.recordAsync(‘Parent record’, parentTable);
let newRecordCount = parentRecord.getCellValue(“FIELD NAME”);
is the syntax for user input, and for button press. that’s the difference between usual script and ‘Run script’ by Automation.
If you need to use Automation ‘Run script’ action, you should define input variable in other way. Mostly, Automations designed to run after triggered by some record (or a group or records). That record represented in “input.config()”. That’s your ‘parentRecord’ for script. But you can’t use it via “getCellValue”.
Instead, at the left side of ‘Run script’ window, you should choose any name, e.g. “numberOfNewRecords”’ and add record field, like you choose ‘dynamic condition’ in ‘Find records’ or whatever.
your input data will be:
let newRecordCount = input.config().numberOfNewRecords;