Phu Nguyen
June 1, 2024
•
15 min read
In the previous blog, we learned how to create a single image/file uploader in Retool. Today, we'll create a multiple image/file uploader, explore its differences, and guide you through the entire process. Get ready to unleash the power of bulk uploads in Retool!
Here's how to craft a reusable module for uploading multiple images or files in Retool:
text1
). Enter a clear and descriptive title for your uploader module.fileDropzone1
) component.gridView1
). This will display uploaded files with informative details. Within the Grid View, you can create:image1
) to display thumbnails.editableText1
) to allow renaming files.checkbox1
) for indicating successful uploads.text2
) above the Grid View. Set the text to display the number of uploaded files in a format like "0/2 Uploaded" (initially showing 0). We'll connect this text component to the upload functionality later.button1
) and set the button text to "Upload" to trigger the upload process.Open the Module settings and add two data inputs:
{{ title.value }}
within text1
component to dynamically display the provided title.To ensure the initial values from the "Initial URL" input are seamlessly reflected on the UI and used for populating existing data, we'll leverage a combination of Retool features:
Query JSON with SQL
script on module load. This dynamic script constructs a SQL query using template literals {{initialUrl.value}}
.uid
) and storing each element with initial include: false
(upload status) and id: uid
(reference) within listViewData
(Retool’s variable) using uid
as the key:initialUrlsGiven.data?.map(e => {
const uid = e.name ?? uuid.v4();
listViewData.setIn([uid], e);
listViewData.setIn([uid, 'include'], false);
listViewData.setIn([uid, 'id'], uid);
});
gridView1
to {{Object.values(listViewData.value)}}
.In gridView1
, we will change:
image1
and add “Click” event handler to open URL in a new tab.editableText1
and add “Blur” event handler to create new or update field name
in listViewData
.checkbox1
and add “Change” event handler to update field include
in listViewData
.In fileDropzone1
, we will also add a script in “Parse” event handler, it iterates through selected files, creating new entries in listViewData
(if needed) with name
, type
, id
(set to name
), and include: false
(initial upload status) using the file's name as the key:
fileDropzone1.files?.map(e => {
if(listViewData.value?.[e.name] == null){
const uid = e.name;
listViewData.setIn([uid, 'id'], e.name);
listViewData.setIn([uid, 'name'], e.name);
listViewData.setIn([uid, 'type'], e.type);
listViewData.setIn([uid, 'include'], false);
}
});
Open the Module settings and add an output. Here's the exciting part: we'll use a transformer listData
to transform the uploaded images data (listViewData
) into a structured array format. Each element in the array will be an object containing:
createdAt
: Timestamp of the upload.name
: Name of the uploaded image.url
: URL of the uploaded image.type
: Type of the uploaded file (e.g., image/jpeg).return {{ Object.values(listViewData.value)?.filter(f => f.include === true && f.url !== null).map((e) => Object({
"createdAt" : e.createdAt,
"name" : e.name,
"url" : e.url,
"type" : e.type,
}))
}};
Creating query to upload multiple images/files to Google Cloud StorageWe've built a user-friendly interface within Retool, and now it's time to tackle the final challenge – uploading files and images to your Google Cloud Storage bucket.
Before diving into the upload query, ensure you've established a secure connection between Retool and Google Cloud Storage. This typically involves creating service accounts and assigning the necessary permissions. You can find a helpful guide on this process in the following blog post "How to connect Retool with Google Cloud Storage" (https://retoolers-io.webflow.io/blog-posts/how-to-connect-retool-with-google-cloud-and-manage-api-keys).
Assuming you've successfully linked Retool and Google Cloud Storage, let's create a query named uploadImages
specifically designed to upload images along with their metadata:
async function uploadImages() {
for (let i = 0; i < fileDropzone1.value?.length; i++) {
const id = fileDropzone1.value[i].name;
if (
listViewData.value?.[id]?.include === false &&
!listViewData.value?.[id]?.url
) {
const mimeType = fileDropzone1.value[i].type;
const extension = mimeType.split("/").pop();
localStorage.setValue("fileInput", `${uuid.v4()}.${extension}`);
localStorage.setValue("fileExtension", mimeType);
await uploadToGCS.trigger({
additionalScope: { id: id },
onSuccess: (data) => {
listViewData.setIn(
[id, "url"],
data.signedUrl.split("?GoogleAccessId")[0]
);
listViewData.setIn([id, "createdAt"], new Date());
listViewData.setIn([id, "include"], true);
},
onFailure: (error) => {
utils.showNotification("Error", error, "error", "3s");
},
});
await setMetadata.trigger();
}
}
}
await uploadImages();
This query iterates through fileDropzone1
files. For each file needing upload (not uploaded yet and no URL):
url
, timestamp
and include
in listViewData
.Now, let's delve deeper into the specifics of each step within the Retool query.
Grabs MIME type and extension from the selected file, store a unique filename for uploading by using Retool's built-in functions uuid.v4()
.
Let's build the upload functionality using GUI, we use additionalScope id
from query into Uploaded data
field:
Enhance your upload functionality by including metadata for the uploaded files/images:
Finally, create Click event handler uploadImages.trigger()
in button1
and update value in text2
.
Now, let's test the module's functionality by creating an app in Retool using this module and uploading a PDF file, a png image and a jpg image.
If uploading successfully, you should see the files listed with their respective thumbnails, names, and upload statuses updated in real-time. This confirms that the module is functioning as intended and that your files are successfully uploaded to Google Cloud Storage.
Congratulation! You've successfully created a Multiple Image/File Uploader Module in Retool, enhancing your application with robust bulk upload capabilities. Now, you can easily manage and upload multiple files, streamlining your workflow and improving efficiency.
Ready to bring your dashboard vision to life? Contact Retoolers today, and let us help you create a powerful, intuitive dashboard that meets your exact requirements.