Sep 12, 2024 11:16 AM
TypeError: record.getCellValue(...) is null
Solved! Go to Solution.
Sep 12, 2024 10:27 PM - edited Sep 12, 2024 10:39 PM
Hi,
insert function somewhere before loop
const addlnk=(arr,lnk)=>[...new Set(arr? [...arr.map(a=>a.id),lnk]:[lnk])].map(x=>({id:x}))
use:
await table.updateRecordAsync(record, {
'People_Link': addlnk(record.getCellValue('People_Link'),linkID)
})
It takes all IDs from existing linked records (if they exist) + new, puts into Set (to remove possible duplicate), spread back to array of IDs and map it to array of objects {id: X}
p/s/ I don't know how do you looping through list, but if you have list of records and possibly their IDs, why add single ID to each record, while you can update just one record (in other table, the 'owner' of linkID)
Sep 12, 2024 05:08 PM
Check whether it's empty, and if it is make it an empty array
const currentPeopleLink = record.getCellValue('People_Link') || [];
await table.updateRecordAsync(record, {
'People_Link': [
...currentPeopleLink,
{ id: 'linkID' }
]
});
Sep 12, 2024 05:21 PM
@TheTimeSavingCo Thank you. I also came upon another issue... In the updateRecord, if that ID is already in the field, it throws an error that the record already exists. I added this chunk. If someone has a better solution I am all ears.
Sep 12, 2024 10:27 PM - edited Sep 12, 2024 10:39 PM
Hi,
insert function somewhere before loop
const addlnk=(arr,lnk)=>[...new Set(arr? [...arr.map(a=>a.id),lnk]:[lnk])].map(x=>({id:x}))
use:
await table.updateRecordAsync(record, {
'People_Link': addlnk(record.getCellValue('People_Link'),linkID)
})
It takes all IDs from existing linked records (if they exist) + new, puts into Set (to remove possible duplicate), spread back to array of IDs and map it to array of objects {id: X}
p/s/ I don't know how do you looping through list, but if you have list of records and possibly their IDs, why add single ID to each record, while you can update just one record (in other table, the 'owner' of linkID)
Sep 13, 2024 05:27 AM
This is awesome! Can you explain to me what is happening in the opening const? I know you explain it in writing below, which is great, but the syntax is confusing to me.
Thanks again!
Jon
Sep 16, 2024 06:08 AM - edited Sep 16, 2024 06:13 AM
Hi,
well, I'll try. writing such explanations is a good mind exercise and helps me to place a knowledge in a better shape in my own head.
actually, this is a function with 2 parameters:
function addlnk( arr, lnk ) {
.....
return new_value
}
names 'arr' , 'lnk' - chosen by me. no need to follow naming conventions, because these variables live only inside "arrow-function" (in the line const addlnk=(arr,lnk)=>..... ). using descriptive names for variables is important, but in Airtable script is a chain of array transforming functions, where you have to get array of input data and form array of output data. so I would rather think how to name a function, but I prefer to not care about single variables inside them. rec | r for records, fld | f for fields , (n=>n) - standard "nonul" filter and so on...
arr - current value of a cell, array of objects like { id: 'recXyZ123AbCDef', name:' Name is a value of primary field' }
lnk - id of new record to add
or, another possible case:
Now, look at this part:
arr? [...arr.map(a=>a.id),lnk]:[lnk]
its the same as
if (arr) { [... arr.map(a=>a.id), lnk] } else { [lnk] }
If cell value is not null, then (arr) is true, otherwise (arr) is false
( just a quick reference: other 'falsy' values are 0 (zero), "" (empty string) , undefined, NaN and some rare stuff...)
arr.map(a=>a.id): map is operator that takes array, process it through small arrow-function and returns array of processed results. Here it takes array of objects , and returns array of IDs
Also take a note about using the 3 dots, spread operator
Now about Set
I think, this example explains it better
and finally, this:
Conclusion:
to update a cell of linked field, we need to extract IDs of current existing links , add new link ID (or just a new ID if a cell was empty). Then we dedupe our list of IDs.
The last important step: we have array of IDs, and we need to transform it back to the array of objects {id: 'rec123XYZabc' }
and that is performed by part
.map(x=>({id:x}))
Important rule: when your arrow-function returns object, you need to wrap it into round brackets
otherwise, if you write ' x=>{ ' JS thinks you are starting a block of operators
When you write one-line arrow function, instead of usual function you don't need to use return word
I think that's all about this. Please don't hesitate to ask if you have any questions.