Capturing images in mobile app using retool storage

I am using an ImageInput to capture photos or upload photos from the mobile app. I have checked the 'Upload File to Retool Storage' option. This makes sure that the photos are getting uploaded.

But I also want to make sure that my database entry for the current Item stores away the file name or file id for association with the uploaded images. I set up 'Capture' event trigger to store away the filename. But am getting null for name or file id. I believe this is happening because the upload is happening on close.

I am looking for the recommended way to store the file id (retool storage) in the retool db for file to Item association. Any help is appreciated.

One issue you may be experiencing is the upload happens asynchronously, so if you also save to your DB on close then you won't have the filename by then. Can you share more about how things are wired up? Screenshots, etc?

1 Like

Here is how the ImageInput is configured

And here is how the 'Capture' event handler is setup.
Screenshot 2023-10-20 at 12.07.31 PM

I am getting the upload everytime. The issue is the db association. I get null sometimes. I believe it is the async upload that you mentioned.

What is the recommended way to do this ? Should I be listening to an event, since the upload is async. Ideally I want the filename of the image dropped into DB

OK. I think I can wait till the user presses the button to complete the job (after taking photos). Hopefully that gives enough time for the photos to upload. Will give that a try.

Yeah unfortunately we don't currently have an event that waits until the upload completes. The recommended way to do this is to include this in a Form and disable the form's submit button while the upload is still happening. The other option is to implement the upload behavior manually but that's a lot more work. I've filed a ticket internally to make this flow easier.


@gzellome and @bca

Got a workaround. It uses the JSON with SQL query trick that turns any property into an event handler.

Create a JSON with SQL Query and set its Query to select {{imageInput1.files[0].retoolStorageId}}

Add your logic to insert/update your database in the Success handler.

In the Advanced tab set the Disable Query to prevent runs if there is no valid retoolStorageId: {{!imageInput1.files[0]?.retoolStorageId}}

The Query will run every time imageInput1.files changes. That can happen when the component is cleared or when the image is first captured. We use the Disable Query property to filter those out.

Once we know we have a valid retoolStorageId our hander gets triggered. This is my handler:

const file = imageInput1.files[0]

const scope = {
        file_type: file.type,
        storage_id: file.retoolStorageId,
        uri:  file.uri

if (imageInput1.files.length === 1) {
  await qryProjectPhotoInsert.trigger({
      additionalScope: scope
  await getProjects.trigger()


This is not torture tested, but is working for now.

1 Like