How do I display ~100 images in a grid from a postgres DB query

I have a grid in the module builder as such...

Essentially, I want a way to populating this with images based on a key I might set from a postgres DB query. The order matters as each image has a "coordinate" so the top left is "A1", the top right is "A8", bottom left is "H1" and bottom right is "H8" so you can work out all the others. I renamed all the images "A1","A2" etc. but now I need to connect the e.g. SQL query

SELECT COORDINATE, URL FROM TBLIMAGES

It is also calling from a private bucket (retool has the resource added) so I need to run a google cloud request for each image and populate them with img.body.

@griffxbio

Hey there :wave:

Can I ask what exactly the return is from your postgres query? Can you share an example of what you have tried here?

@lauren.gus Umm, it is just that exact query above and so a table is {{ table.data }} and I have in one column the coordinate and in another column the URL.. Note however that there is an extra step that creates the coordinate from the filename so technically the "coordinate" or "well" you see in the image is a calculated column (not sure if that is accessible). In fact, SignedURL is also generated from a JS function applied to a list of URLs in another table (see Option 3 below for more info).

Option 1 - Change imagesource

Set a filter of some kind in the image source (syntax is broken as I don't know how to use filter properly). Btw, the documentation on this in the docs, doesn't clearly have examples of how this filter works, unless I missed it. This is as close as I've found, but I don't want to make 100 transformers+filter for each coordinate.

Screen Shot 2022-02-17 at 11.31.47 am

Option 2 - Transformer

I tried to make a transformer to construct a new array mapping "coordinate":"URL"

again the syntax is broken above because I don't get an error. I think I need a formatasArray or something in there.

Option 3 - Transformer when getting the imageList from Google Bucket.

The signedURL comes from another query run earlier outlined here on the forum.

Essentially getting a single image's signedURL row by row.

const promises = table2.data.map(row => {
    return getImageSingle.trigger({
        additionalScope: {
            name: row.name,
            well: row.well
        }
    });
});

return Promise.all(promises);

Now I thought I could just add a transformer at the end of this and would do the trick but my this transformer is also broken.

Screenshot from 2022-02-17 13-34-36

Summary

Gentle reminder that I am looking for an dictionary object or array that maps coordinate to signedURL in the table such that in the imagesource I can just go transformer.data['A3'] and it provides the SignedUrl string to the component.

I actually even thought a simple .map would work such as

return {{table3.data}}.map(x => ( { x.well : x.signedUrl } ))

but well and signedUrl are calculated columns I guess so this doesn't work either. :frowning:

As you can see, I have actually spent quite some time on this with no relief in sight.

Hi @griffxbio, It looks like you might need to reference the table.columnMappers value.

I hope that helps!

Thanks @everett_smith - this is very close! Though, rather than being able to access this via:

{{transformer3.value[0]['key']}}

Would there be a way to just expose the array so I don't have to index?

i.e. {{transformer3.value['key']}} --> value

Here is that code from the screenshot you provided (which does work as you outlined), I'm fairly sure it's just a small modification I need to just unpack the array.

let data = {{ formatDataAsArray(tbltimepoint.columnMappers ) }}
return data.map (x => {
    let obj = {}
    obj[x['Custom Column 4']] = x['Custom Column 1']
    return obj
})

It is basically exactly this goal I'm aiming at. I'll try tinker in the meantime.

Update

Got it!

let data = {{ formatDataAsArray(tbltimepoint.columnMappers ) }}
let dictionary = Object.assign({}, ...data.map((x) => ({[x['Custom Column 4']]: x['Custom Column 1']})));
return dictionary

// returns
// key1:value1
// key2:value2
...

Thanks @everett_smith for the help!