How to get asynced data from triggered query inside other query

Hope someone can help me and point to a mistake. I have a query that takes a filename and returns back a URL for this filename. The main query constructs a collection of entities with names and URLs, but in the end, the list is empty, as all URLs are resolved after the main loop finishes.

const collections = [
  {"id":1,"images":[{"name":"fox.jpeg"},{"name":"hamster.jpeg"}]},
  {"id":2,"images":[{"name":"lion.jpeg"},{"name":"turtle.jpeg"}]}]
let urlCollections = []

collections.forEach(collection =>{
  let urlCollection={"id":collection.id,"images":[]}
  collection.images.forEach(image=>{
    getAssetUrl.trigger({//query that returns back a url for a given filename from the assets table
      additionalScope: {"filename":image.name},
      onSuccess: function(url) {
        console.log('URL='+url);//all urls are resolved correctly
        urlCollection.images.push({"name": image.name, "url": url })
  	  }
    })
  })
  urlCollections.push(urlCollection)
})
return urlCollections

result is empty

[{"id":1,"images":[]},{"id":2,"images":[]}]

Hey @yeugenius and welcome to the retool community :))

Your queries are being resolved after the whole query finished because they are promises.

Try:

  • changing .forEach to a boring for() loop because .forEach` is executing the function given for all objects simultaneously.
  • Change your trigger query to
...

const assetURL = await new Promise((resolve) => {
  getAssetUrl.trigger({
    additionalScope: {"filename":image.name},
    onSuccess: (data) => {
      resolve(data);
    },
  });
});

urlCollection.images.push({"name": image.name, "url": assetURL })

...

Does that work for you?

Yes, it works, thanks! But it works if you use both - for() and "await new Promise() trigger" at the same time. I have tried to use each approach separately and it doesn't work.

1 Like