Skip to main content
Solved

How to extract all URLs in a single attachment


Hello,


Can someone help me to write a code to extract all the URLs associated with my attachment in a particular record?


As you can see here, i have 3 photos where i need to generate “https://dl.airtablexxx1,https://dl.airtablexxx2,https://dl.airtablexxx3” in a field named “joined”



Thank you for helping me

Best answer by Rupert_Hoffsch1

kennypurnomo wrote:

Is it because i have records which has empty attachment field? If yes, how can i ignore those records?


Sorry, didn’t check for that. Here you go:


const table = base.getTable("Table 5")

const recordsQuery = await table.selectRecordsAsync();



let updateArray = [];



// iterate over all records

recordsQuery.records.forEach(record => {

    const attField = record.getCellValue("Attachment 1");



    // iterate over object and save as url

    if(attField) {

        let urlArray = [];

        attField.forEach(item => urlArray.push(item.url))

        const urlString = urlArray.join(', ')



        updateArray.push({id: record.id, fields: {"Joined": urlString}})

    }

})



// update records

while (updateArray.length > 0) {

    await table.updateRecordsAsync(updateArray.slice(0, 50));

    updateArray = updateArray.slice(50);

}

View original
Did this topic help you find an answer to your question?

14 replies

Hi Kenny, just wrote a script that does the job (please change table name in base.getTable("...") as well as the attachment field in const attField = record.getCellValue("..."); and the field to be updated at the end):


const table = base.getTable("Table 5")

const record = await input.recordAsync("Please select record", table);



// Select attachment field

const attField = record.getCellValue("Attachment 1");



// iterate over object and save as url

let urlArray = [];

attField.forEach(item => urlArray.push(item.url))

const urlString = urlArray.join(', ')



// update field

await table.updateRecordAsync(record.id, {

    "Joined": urlString,

})


This script works with a button as well as by selecting the record in the script. Please let me know if you have any questions!


Rupert_Hoffsch1 wrote:

Hi Kenny, just wrote a script that does the job (please change table name in base.getTable("...") as well as the attachment field in const attField = record.getCellValue("..."); and the field to be updated at the end):


const table = base.getTable("Table 5")

const record = await input.recordAsync("Please select record", table);



// Select attachment field

const attField = record.getCellValue("Attachment 1");



// iterate over object and save as url

let urlArray = [];

attField.forEach(item => urlArray.push(item.url))

const urlString = urlArray.join(', ')



// update field

await table.updateRecordAsync(record.id, {

    "Joined": urlString,

})


This script works with a button as well as by selecting the record in the script. Please let me know if you have any questions!


PS: Works for any number of attachments / URLs in a given field


  • Author
  • Known Participant
  • 34 replies
  • May 25, 2022
Rupert_Hoffsch1 wrote:

Hi Kenny, just wrote a script that does the job (please change table name in base.getTable("...") as well as the attachment field in const attField = record.getCellValue("..."); and the field to be updated at the end):


const table = base.getTable("Table 5")

const record = await input.recordAsync("Please select record", table);



// Select attachment field

const attField = record.getCellValue("Attachment 1");



// iterate over object and save as url

let urlArray = [];

attField.forEach(item => urlArray.push(item.url))

const urlString = urlArray.join(', ')



// update field

await table.updateRecordAsync(record.id, {

    "Joined": urlString,

})


This script works with a button as well as by selecting the record in the script. Please let me know if you have any questions!


Thanks for your effort. Can we RUN this script in the dashboard so that the script runs for the WHOLE records?


kennypurnomo wrote:

Thanks for your effort. Can we RUN this script in the dashboard so that the script runs for the WHOLE records?


I assume with “dashboard” you mean the app section on the right side? In this case we would need to iterate over all records instead of selecting a single record (via button or input in script). Then we run the script for every record just like before:


const table = base.getTable("Table 5")

const recordsQuery = await table.selectRecordsAsync();



// iterate over all records

recordsQuery.records.forEach(async record => {

    const attField = record.getCellValue("Attachment 1");



    // iterate over object and save as url

    let urlArray = [];

    attField.forEach(item => urlArray.push(item.url))

    const urlString = urlArray.join(', ')



    // update field

    await table.updateRecordAsync(record.id, {

        "Joined": urlString,

    })

})


You will still have to replace those field names in red of course.


Rupert_Hoffsch1 wrote:

I assume with “dashboard” you mean the app section on the right side? In this case we would need to iterate over all records instead of selecting a single record (via button or input in script). Then we run the script for every record just like before:


const table = base.getTable("Table 5")

const recordsQuery = await table.selectRecordsAsync();



// iterate over all records

recordsQuery.records.forEach(async record => {

    const attField = record.getCellValue("Attachment 1");



    // iterate over object and save as url

    let urlArray = [];

    attField.forEach(item => urlArray.push(item.url))

    const urlString = urlArray.join(', ')



    // update field

    await table.updateRecordAsync(record.id, {

        "Joined": urlString,

    })

})


You will still have to replace those field names in red of course.


Sorry it was too early here and didn’t think about API rate limits :grinning_face_with_big_eyes: (15 writes per second and 50 records in one call). I changed the script and it should work for any number of records:


const table = base.getTable("Table 5")

const recordsQuery = await table.selectRecordsAsync();



let updateArray = [];



// iterate over all records

recordsQuery.records.forEach(record => {

    const attField = record.getCellValue("Attachment 1");



    // iterate over object and save as url

    let urlArray = [];

    attField.forEach(item => urlArray.push(item.url))

    const urlString = urlArray.join(', ')



    updateArray.push({id: record.id, fields: {"Joined": urlString}})

})



// update records

while (updateArray.length > 0) {

    await table.updateRecordsAsync(updateArray.slice(0, 50));

    updateArray = updateArray.slice(50);

}


Rupert_Hoffsch1 wrote:

Sorry it was too early here and didn’t think about API rate limits :grinning_face_with_big_eyes: (15 writes per second and 50 records in one call). I changed the script and it should work for any number of records:


const table = base.getTable("Table 5")

const recordsQuery = await table.selectRecordsAsync();



let updateArray = [];



// iterate over all records

recordsQuery.records.forEach(record => {

    const attField = record.getCellValue("Attachment 1");



    // iterate over object and save as url

    let urlArray = [];

    attField.forEach(item => urlArray.push(item.url))

    const urlString = urlArray.join(', ')



    updateArray.push({id: record.id, fields: {"Joined": urlString}})

})



// update records

while (updateArray.length > 0) {

    await table.updateRecordsAsync(updateArray.slice(0, 50));

    updateArray = updateArray.slice(50);

}


Thanks mate! It’s very useful.


  • Author
  • Known Participant
  • 34 replies
  • May 25, 2022
Rupert_Hoffsch1 wrote:

Sorry it was too early here and didn’t think about API rate limits :grinning_face_with_big_eyes: (15 writes per second and 50 records in one call). I changed the script and it should work for any number of records:


const table = base.getTable("Table 5")

const recordsQuery = await table.selectRecordsAsync();



let updateArray = [];



// iterate over all records

recordsQuery.records.forEach(record => {

    const attField = record.getCellValue("Attachment 1");



    // iterate over object and save as url

    let urlArray = [];

    attField.forEach(item => urlArray.push(item.url))

    const urlString = urlArray.join(', ')



    updateArray.push({id: record.id, fields: {"Joined": urlString}})

})



// update records

while (updateArray.length > 0) {

    await table.updateRecordsAsync(updateArray.slice(0, 50));

    updateArray = updateArray.slice(50);

}



Rupert, i got strikethrough syntax there. Is it okay to proceed?


  • Author
  • Known Participant
  • 34 replies
  • May 25, 2022

I got this error…


The “Joined” field is Single Text field in my side. Is this correct?


  • Author
  • Known Participant
  • 34 replies
  • May 25, 2022
kennypurnomo wrote:

I got this error…


The “Joined” field is Single Text field in my side. Is this correct?


Is it because i have records which has empty attachment field? If yes, how can i ignore those records?


kennypurnomo wrote:

Is it because i have records which has empty attachment field? If yes, how can i ignore those records?


Sorry, didn’t check for that. Here you go:


const table = base.getTable("Table 5")

const recordsQuery = await table.selectRecordsAsync();



let updateArray = [];



// iterate over all records

recordsQuery.records.forEach(record => {

    const attField = record.getCellValue("Attachment 1");



    // iterate over object and save as url

    if(attField) {

        let urlArray = [];

        attField.forEach(item => urlArray.push(item.url))

        const urlString = urlArray.join(', ')



        updateArray.push({id: record.id, fields: {"Joined": urlString}})

    }

})



// update records

while (updateArray.length > 0) {

    await table.updateRecordsAsync(updateArray.slice(0, 50));

    updateArray = updateArray.slice(50);

}


Rupert_Hoffsch1 wrote:

Sorry, didn’t check for that. Here you go:


const table = base.getTable("Table 5")

const recordsQuery = await table.selectRecordsAsync();



let updateArray = [];



// iterate over all records

recordsQuery.records.forEach(record => {

    const attField = record.getCellValue("Attachment 1");



    // iterate over object and save as url

    if(attField) {

        let urlArray = [];

        attField.forEach(item => urlArray.push(item.url))

        const urlString = urlArray.join(', ')



        updateArray.push({id: record.id, fields: {"Joined": urlString}})

    }

})



// update records

while (updateArray.length > 0) {

    await table.updateRecordsAsync(updateArray.slice(0, 50));

    updateArray = updateArray.slice(50);

}


Strikethrough syntax is fine


  • Author
  • Known Participant
  • 34 replies
  • May 25, 2022
Rupert_Hoffsch1 wrote:

Sorry, didn’t check for that. Here you go:


const table = base.getTable("Table 5")

const recordsQuery = await table.selectRecordsAsync();



let updateArray = [];



// iterate over all records

recordsQuery.records.forEach(record => {

    const attField = record.getCellValue("Attachment 1");



    // iterate over object and save as url

    if(attField) {

        let urlArray = [];

        attField.forEach(item => urlArray.push(item.url))

        const urlString = urlArray.join(', ')



        updateArray.push({id: record.id, fields: {"Joined": urlString}})

    }

})



// update records

while (updateArray.length > 0) {

    await table.updateRecordsAsync(updateArray.slice(0, 50));

    updateArray = updateArray.slice(50);

}


Wow. This is the solution. Thanks A lot


  • Author
  • Known Participant
  • 34 replies
  • May 26, 2022
Rupert_Hoffsch1 wrote:

Sorry, didn’t check for that. Here you go:


const table = base.getTable("Table 5")

const recordsQuery = await table.selectRecordsAsync();



let updateArray = [];



// iterate over all records

recordsQuery.records.forEach(record => {

    const attField = record.getCellValue("Attachment 1");



    // iterate over object and save as url

    if(attField) {

        let urlArray = [];

        attField.forEach(item => urlArray.push(item.url))

        const urlString = urlArray.join(', ')



        updateArray.push({id: record.id, fields: {"Joined": urlString}})

    }

})



// update records

while (updateArray.length > 0) {

    await table.updateRecordsAsync(updateArray.slice(0, 50));

    updateArray = updateArray.slice(50);

}


@Rupert_Hoffschmidt, unfortunately this script only works if the “Joined” field is initially empty.


When i update the images in “attachment” field, running this script doesn’t change what inside the “Joined” field.


Is there any script line should i put so that it always updates?


kennypurnomo wrote:

@Rupert_Hoffschmidt, unfortunately this script only works if the “Joined” field is initially empty.


When i update the images in “attachment” field, running this script doesn’t change what inside the “Joined” field.


Is there any script line should i put so that it always updates?


Hi Kenny, yes it only works for adding attachments, but not deleting attachments from the field. I’ve added some code (if attField == null...) for deleting whatever is in the field IF the attachment is empty. I’ve tested all possible combinations and it seems to work well:


const table = base.getTable("Table 5")

const recordsQuery = await table.selectRecordsAsync();



let updateArray = [];



// iterate over all records

recordsQuery.records.forEach(record => {

    const attField = record.getCellValue("Attachment 1");



    // iterate over object and save as url

    if(attField) {

        let urlArray = [];

        attField.forEach(item => urlArray.push(item.url))

        const urlString = urlArray.join(', ')



        updateArray.push({id: record.id, fields: {"Joined": urlString}})

    }

    if(attField == null) {

        updateArray.push({id: record.id, fields: {"Joined": ""}})

    }

})



// update records

while (updateArray.length > 0) {

    await table.updateRecordsAsync(updateArray.slice(0, 50));

    updateArray = updateArray.slice(50);

}


Reply