Help

Re: Scripting to MultiSelect Linked.. only works when at least one item is in the field

Solved
Jump to Solution
447 0
cancel
Showing results for 
Search instead for 
Did you mean: 
Jon_Eynon
6 - Interface Innovator
6 - Interface Innovator
I am looping through a list of people in a table and adding them to a multiselect linked field in another. I have found and
implemented the following code to update multiselects without deleting the records existing values.
I have found that this only works IF the record contains a value. I get the following error:
TypeError: record.getCellValue(...) is null
Once I push a value into the record manually and then run the script it works great.
I need to be able to push the FIRST instance into that field and then also add on top of that.
Thanks in advance.
// This script only works if there is already a value in People Link. In my loop I might need to update
add up to 3 people into this record. How can I push the first one in and then run this after?
What would my if look like? //
 
table.updateRecordAsync(record, {
   'People_Link': [
       ...record.getCellValue('People_Link'),
       { id: linkID}
    ]
})
1 Solution

Accepted Solutions

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)

See Solution in Thread

5 Replies 5

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' }
    ]
});

@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.

let foundIt="No";
            // I am going to open the record I want to update and loop through the existing
// IDs. If the one I am trying to bring in exists, foundIt=Yes 
let foundIt="No";
for (let people_link of record.getCellValue('People_Link')) {
                  if(people_link.id==linkID){
                       foundIt="Yes";
                       output.text("we found a match already. Ignore");
                   };
             }
             if(foundIt=="No"){
            await table.updateRecordAsync(record, {
               'People_Link': [
                    ...record.getCellValue('People_Link'),
                 { id: linkID}
                ]
              })
             }

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)

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

Alexey_Gusev
13 - Mars
13 - Mars

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 | 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

Alexey_Gusev_0-1726486385878.png

or, another possible case:

Alexey_Gusev_1-1726486654142.png

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

Alexey_Gusev_2-1726487478724.png

Also take a note about using the 3 dots, spread operator

Alexey_Gusev_3-1726487903717.png


Now about Set
I think, this example explains it better

Alexey_Gusev_4-1726488724328.png

 

Alexey_Gusev_5-1726488794766.png

and finally, this:

Alexey_Gusev_6-1726489174667.png

Alexey_Gusev_7-1726489199112.png

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.