New: Uploadable image column type on Table

Hi all! We are thrilled to announce the cloud launch of the uploadable image column type on Table!


Now, when you set an Image column type in your Table component (which already existed before this feature), you can now set this Allow uploading images checkbox, which will let you upload images from your local file system:

|482.658064516129x225.5900212701272


We also have added 2 more properties that get set when you check the above checkbox:

  • Upload file to Retool Storage: if checked, this will automatically upload the image that you’ve uploaded to Retool Storage
  • Replace file with same name: if checked, this will overwrite a file with the same name in Retool Storage

We have launched this feature to 100% of cloud users, and plan to get it out to on-prem version 3.39-edge and 3.47-stable. Please let us know in this thread if you have any comments/suggestions.

Happy building!

– Darya

1 Like

Under event handler is there an action that can trigger after an image is added? In case we want to upload something other than retool storage.

@metechnologies So far we have not implemented this feature. I have noted in though internally, and will let you know if we plan to implement it!

@metechnologies I take back what I said! You can access this event Change cell that should fire when you change the cell (which will happen when you upload a new image). It just isn't called 'On Image Upload', but should do what you mentioned.

1 Like

Awesome -- I see the table.changesetArray[0].columnImage will store the base64Data. How would we access 'type' like we could on a fileUpload component? (eg to get image/png, image/jpeg etc)

Also, if there is an existing image, you cannot click it to upload a different one. Is this intentional, is there a toggle for this somewhere? I want to be able to click existing images in the table to upload a new one.

@bag For your second question, you should still be able to upload a new image through clicking the ... menu that appears in that cell on hover:

image

For your first question, there is currently no way to access this information. I have filed it as a request internally, and will update here with any updates!

@Darya_Verzhbinsky
How can I upload images from this type of column to GCS bucket? I have set up a resource for GCS and also created a bucket. Here is my javascript for this

const uploadToGCS = async (file, newFileName) => {
    console.log("Entering uploadToGCS function");
    const bucketName = 'chainlabs-screenshots'; // Your GCS bucket name
    const gcsResource = 'Chainlabs GCS'; // Your GCS resource name in Retool
    // const base64Data = file.replace(/^data:image\/(png|jpg);base64,/, ''); // Remove base64 header
    const base64Data = file; // Remove base64 header
    
    const filePath = newFileName; // Dynamic file path

    if (!base64Data) {
        throw new Error('Invalid base64 string');
    }

    try {
        // Convert base64 to binary data
        console.log("Base64 data length:", base64Data.length);
        const byteCharacters = atob(base64Data);
        const byteNumbers = new Array(byteCharacters.length);
        for (let i = 0; i < byteCharacters.length; i++) {
            byteNumbers[i] = byteCharacters.charCodeAt(i);
        }
        const byteArray = new Uint8Array(byteNumbers);
        const blob = new Blob([byteArray], { type: 'image/png' });
        console.log("Blob size:", blob.size);
        console.log("Blob type:", blob.type);
        console.log("Blob:", blob);
      

        // Ensure blob is not empty
        if (blob.size === 0) {
            throw new Error('Blob is empty');
        }

        // Upload to GCS using Retool's API call
       const response = await retool.sendResourceRequest({
            resource: gcsResource,
            method: 'PUT',
            url: `https://storage.googleapis.com/upload/storage/v1/b/${bucketName}/o?uploadType=media&name=${filePath}`,
            headers: {
                'Content-Type': 'application/octet-stream' // Using octet-stream for base64 data
            },
            body: base64Data
        });

        console.log('Upload response status:', response.status);
        console.log('Upload response data:', response.data);

        if (!response.ok) {
            throw new Error(`Upload failed: ${response.statusText}`);
        }

        return response;
    } catch (error) {
        console.error('Error during upload:', error);
        throw error;
    }
};

I am getting an error - Error during upload