How to run a REST API/Query for each item in an array and return all results together

Similar to https://docs.retool.com/docs/scripting-retool#section-triggering-a-query-for-each-item-in-an-array, this setup using Async JS promises will make the .data property of this query include ALL of the results of the triggered queries.

Using a Run JS Code type query, we will trigger another query for each item in an array, and after the last is completed return all of the results together in the jsCodeQueryName.data value.

Where get_assignment is a REST Api query, taking an input of {{assignment_id}} , const promises returns a mapping function of each result of the API where we pass in ID as additionalScope.

image

In a copyable format:

const arr = assignment_ids.value //your array of things to iterate over
const query = get_assignment // your query to trigger for each

const promises = arr.map((item) => {
    return query.trigger({
      additionalScope: {
        assignment_id: item //assignment_id would be available inside {{assignment_id}} in the target query when run
      }
   });
});

return Promise.all(promises)

You could then reference the results inside a calculated column of a table for example using {{jsQueryName.data[i]}} in the calculation to have each row display the result.

NOTE: If you pass in any null values to the .map method, this code will return a "Failed to execute 'postMessage' on 'Window': # could not be cloned." error. You'll need to filter out or replace any null values in the array before then.

11 Likes

Could you provide a real example such as you have done in the first example ?

Hi

What we miss is how looks the query get_assignment like and how/where you define assignment_id in it.

cheers

1 Like

Fo anyone passing by.
I had the same kind of question and solve it thank to @Amanda in [calling query1 from query2](Calling query1 from query2).
I think it works whatever query1's nature.
Don't pay attention to the debugger alert.

@alex-w I am new to retool but loving it. Can you share an example where this has been done please. I have tried with the demo data but not able to extract the assignment_id successfully.
Keep getting undefined values. I am using table2.selectedRows for the array source.

Hi @Louis in line 1, can you try table1.selectedRows instead of table1.selectedIndex?

Also, welcome to Retool! Glad you're enjoying it :sunglasses:

Love the platform and see endless use-cases for our industry. Been really stuck on this for some time now ...

When running this JS :slight_smile:

const array = table2.selectedRows
const query = postman

const promises = array.map((id) => {
    console.log(id);
      return query.trigger({
      additionalScope: {
        rowId: id
      }
   });
});

return Promise.all(promises)

I can see the correct rows are read, they are simply not loaded into the rowID object called id

So when looking at the id parameter I would expect to see a value. The result remain NULL regardless of single or multi-selecting rows.

I am expecting to see the value of the selectedRow. Hope this makes sense.

Hi @Louis,

It looks like id is the entire row object, so if you only wanted the id, it would be rowId: id.id.

Or you could re-write it like this:

const promises = array.map((row) => { 
console.log(row); //change this line
return query.trigger({
additionalScope: {
rowId: row.id //change this line
}
});
});

Then, in the postman query, you could reference each row's id by calling {{rowId}}

Changed the query2 code to below:

const array = table1.selectedRows
const query = postman

const promises = array.map((row) => {
    console.log(row);
      return query.trigger({
      additionalScope: {
        rowId: row.id
      }
   });
});

return Promise.all(promises)

The rowID is shown correctly and pulls the correct row number for multi-selected rows, however when I try and call rowID from another resource i.e postman the value returned is null

Having changed {{query2.data['rowID'].user to {{query1.data['0'].user}} I can see the correct user value. I was hoping to use rowID as a dynamic variable but keep getting null regardless.

Hi @Louis,

It should look more like this, where the rowId is not wrapped in quotes

thank you @Tess tried this but still no luck. I will begin again !

Hmm thanks for letting me know :disappointed: If you're open to chatting through this live, this could be a good topic for our office hours!

1 Like