Jul 26, 2021 02:09 PM
Part of my custom APP takes a number of different user inputs from a UI, and writes some of the resultant information as a new record in a table. In particular I want to do the following:
Write a string value to a linked field in an existing table
The string value to be passed is already guaranteed to exist as one of the linked options (since the user selected from a Select menu which is in turn populated from the table.
*There are some other fields which need to be written as part of this record. The code looks something like the following.
`` let machineNameField=tableTasksByMachineNumber.getFieldByNameIfExists(‘Machine Name’);
let machineNamesRecord=useRecords(tableTasksByMachineNumber,machineNameField);
let machineNamesList=machineNamesRecord.map(record=>
{return(record.getCellValueAsString(machineNameField))});
let machineNamesListFormatted=machineNamesList.map(x=>{return({label: x, value:x})});`
Machine Selection
<Select
value={machineId}
options={machineNamesListFormatted}
onChange={setMachineId}
/>
// at this point the machineID variable is set by the useState react hook.
//I want to create the new record on clicking a confirmation dialog, as shown in the below snippet for my event handler
onConfirm={() => {
tableMaintenanceTickets.createRecordsAsync([
{'fields': {
"Machine Number / Station": [{machineId}]
}}]
),
When I run this code I get the following error:
![image|700x183](upload://qPHyZTjvVIwk8Oof7T8himQnCdJ.png)
NOTE: I can create the record when I pass an empty array through the createRecordsAsync method.
Any help/insight would be much appreciated
Solved! Go to Solution.
Jul 26, 2021 06:04 PM
Hey @Justin_Yorick - correct, when setting linked value cells you’ll need the record IDs for the records you’re linking to. This also means that the records you’re linking to need to already exist (in order to have an id). You can grab the id directly from the record record.id
. For example, using some of the code you have above, you could do something like this to format the options for the <Select>
:
let machineNameField = tableTasksByMachineNumber.getFieldByNameIfExists(‘Machine Name’);
let machineNameRecords = useRecords(tableTasksByMachineNumber);
let machineNameOptions = machineNameRecords.map(machineNameRecord => ({
label: machineNameRecord.getCellValueAsString(machineNameField),
value: machineNameRecord.id
}));
after which machineId
should reference the recordId
for the selected machine record. You may need to mix in some null checking to ensure that e.g. a user selected a machine, but hopefully this is helpful. Here is the docs section for linked record cell values.
Cheers,
Billy
Jul 26, 2021 02:13 PM
For some reason the attached screenshot is not loading. below is a copy of the error message I am receiving.
Error: Invalid record format. Please define field mappings using a `fields` key for each record definition object
at https://localhost:9000/__runFrame/bundle.js:11007:53
at Array.map (<anonymous>)
at Table.createRecordsAsync$ (https://localhost:9000/__runFrame/bundle.js:11000:41)
at tryCatch (https://localhost:9000/__runFrame/bundle.js:84105:40)
at Generator.invoke [as _invoke] (https://localhost:9000/__runFrame/bundle.js:84335:22)
at Generator.next (https://localhost:9000/__runFrame/bundle.js:84160:21)
at tryCatch (https://localhost:9000/__runFrame/bundle.js:84105:40)
at invoke (https://localhost:9000/__runFrame/bundle.js:84196:20)
at https://localhost:9000/__runFrame/bundle.js:84231:11
at new Promise (<anonymous>)
Jul 26, 2021 05:27 PM
Hi @Justin_Yorick ,
Sorry you’ve been running into issues here. From your provided code sample, it looks like you’re formatting the createRecordsAsync
argument correctly (docs here), so I’m scratching my head a bit. Is it possible there’s another createRecordsAsync
call somewhere that’s malformatted? Out of curiosity, what version of the @airtable/blocks
SDK are you using in your package.json?
I tried reproing the error on v1.8 but the following sample code worked as expected:
import { initializeBlock, useBase } from "@airtable/blocks/ui";
import React from "react";
function HelloWorldApp() {
const base = useBase();
const table = base.tables[0];
function handleClick() {
table.createRecordsAsync([{ fields: { Name: "Test" } }]);
}
return <button onClick={handleClick}>Create record</button>;
}
initializeBlock(() => <HelloWorldApp />);
EDIT: It does look like there may be a formatting issue with the cell value for “Machine Number / Station” field - if that’s a linked record field, each object will need to be formatted with an id
property (see example in docs here). That said, I don’t think this issue is what’s causing the error message you’re seeing - more of an FYI
Jul 26, 2021 05:48 PM
Thanks for the quick reply @Billy_Littlefield !
So far I do not have any other calls to the createRecordAsync method
From what I’ve seen in other post, I think the issue may be related to the fact that this is a linked field.
The documentation says that to write to linked fields, I need to reference the record Id. I’m not sure what this means since the whole point of this particular function is to create a new record.
Perhaps this is referencing the record Id of the linked record(s) which are the selectable options for this field? If this is the case, do I need to pass the record from the linked record?
Eg,
lets say I have two tables. my function is creating records in table 1. The values of the linked cells are records/fields in table 2.
If if I have option A, option B and option C as possible linked values from table 2, do I need to reference the record Ids (from table two) I wish to write in table 1 when I use the createRecordAsync method?
Jul 26, 2021 06:04 PM
Hey @Justin_Yorick - correct, when setting linked value cells you’ll need the record IDs for the records you’re linking to. This also means that the records you’re linking to need to already exist (in order to have an id). You can grab the id directly from the record record.id
. For example, using some of the code you have above, you could do something like this to format the options for the <Select>
:
let machineNameField = tableTasksByMachineNumber.getFieldByNameIfExists(‘Machine Name’);
let machineNameRecords = useRecords(tableTasksByMachineNumber);
let machineNameOptions = machineNameRecords.map(machineNameRecord => ({
label: machineNameRecord.getCellValueAsString(machineNameField),
value: machineNameRecord.id
}));
after which machineId
should reference the recordId
for the selected machine record. You may need to mix in some null checking to ensure that e.g. a user selected a machine, but hopefully this is helpful. Here is the docs section for linked record cell values.
Cheers,
Billy
Jul 27, 2021 10:48 AM
@Billy_Littlefield
This was the issue!!
Thanks again for the expedient assist