Jan 07, 2022 09:01 AM
Hello everyone!
How could I mimic an action of copying-pasting string value into the linked field with an automation script? Here is what I mean:
Here I can easily copy the value of a string field “task 4” and paste it into linked field “Linked Tasks”. Actually, I paste into this field the property “name” of the object
So, how could I reference this property in a script?
await table.updateRecordAsync(rec, {
"Linked Tasks": [{ name: rec.getCellValueAsString("Manually Entered Tasks") }]
})
This assignment doesn’t work, but I stuck finding correct way. Any suggestion is much appreciated.
Jan 07, 2022 11:45 AM
Hi,
The answer is depends on your goal.
When you copy-paste something into linked field, Airtable iterates all possible values to link (ignoring “Limit record selection to a view”).
If it found nothing, it will create new record and link to it. That’s (when you mess with linking at first table and receive unexpected new records in second, and even doesn’t know it) annoying at the start, but it’s a powerfull feature for performing some difficult tasks without code.
turning to your question, i think it uses rec.name, which is usually same as getCellValue(asString?) of a primary field. but i’m not sure 100%
Jan 08, 2022 12:07 AM
Hi, @Alexey_Gusev, the problem which I face is that the linked field “Linked Tasks” doesn’t accept provided value throwing error message: Field “fldXXX” cannot accept the provided value. And it seems that I am not referencing it correctly. Looking at the structure of the field data I can see that it is an array containing objects with properties including id and name. I am trying to set name property, but have no idea how to reference it correctly.
And of course, I understand that pasting data that doesn’t exist in a linked table is going to create a new record, but currently this is not my case.
Jan 08, 2022 10:24 AM
So far did not find better solution than passing id instead of name, which is searched through loaded records using array find function. The function is inserted directly into value place:
await table.updateRecordAsync(i, {
"Linked Tasks": [{id: selTasks.records.find(rec => rec.name === taskName).id}]
})
This works, but the bad thing is that find possibly can return undefined which will throw an error getting id of undefined.
Jan 11, 2022 11:31 AM
Ok, if you want just to link, you don’t need to mimic copy-paste (and you can’t do it simple)
If you check API, you will see
You can’t just put name, because there may be 1,2 or more records with such name for you to decide which one to use. Or what to do if zero match.
I think, you should convert to smth like
let rec=selTasks.records.find(r => r.name === taskName);
and then
if(rec) await table.updateRecordAsync(i, {"Linked Tasks":[{id: rec.id}]})
If you want to do the same for multiple records in a loop, you should turn
.updateRecordAsync to .updateRecordsAsync
if you want to link all whose name matches, you should just change ‘find’
to ‘filter’ (and remember that you’ll get not a rec, but array of recs)
also, you can create Map object
let selTaskMap=new Map(selTasks.records.map(r=>[r.name,r.id]));
map needs “array of arrays[key,value]” to init, or start with empty new Map()
, and then Map.set(key, value)
in a loop.
and then check
if selTaskMap.has(name)
and get id from name: myId=selTaskMap.get(name)
i started using Set and Map objects (with difficulties) when i learned JS, and they are very useful for some tasks