Build an AWS S3 Browser with ToolJet
Tags: programming, webdev, opensource, javascript
Published: 2023-08-03 10:05:53

Amazon S3 (Simple Storage Service) has emerged as a popular choice due to its reliability, scalability, and cost-effectiveness. S3 service provides developers with a flexible object storage service, making it a great option for storing and retrieving any amount of data at any time.

However, interacting with Amazon S3 programmatically can sometimes be a daunting task. In this tutorial, we will introduce you to an efficient approach that simplifies the process of building a powerful AWS S3 Browser App without the need for extensive development work.

## What is ToolJet?

[ToolJet](https://github.com/ToolJet/ToolJet) is an open-source low-code framework that enables us to build full-stack web applications within a few minutes. With ToolJet, you can create standalone fully-functional full-stack applications or embed applications into other websites.

ToolJet allows you to build applications that use relational and non-relational databases, REST APIs, OpenAI technologies, and cloud storage like [Google Cloud Storage](https://cloud.google.com/storage), [AWS S3](https://aws.amazon.com/pm/serv-s3), and [Minio](https://min.io/). It is an excellent development tool helping individuals, developers, and businesses create and ship products faster.

**Before we continue**
I would be super happy if you could give us a star! And let me also know in the comments section. ❤️

[https://github.com/ToolJet/ToolJet](https://github.com/ToolJet/ToolJet)

![https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExZjlhNzRjMWJlYzgyNWZjYjcyOGMxYjJiYjQxOTQzYTU1NTg5YzAzNiZjdD1n/dfbMVqwq8GrC19xSEF/giphy.gif](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExZjlhNzRjMWJlYzgyNWZjYjcyOGMxYjJiYjQxOTQzYTU1NTg5YzAzNiZjdD1n/dfbMVqwq8GrC19xSEF/giphy.gif)


## Overview

To develop this application, we will utilize ToolJet along with its S3 integration, enabling us to perform various operations. These operations include fetching a list of all available buckets, retrieving data from selected buckets, and uploading data into the chosen buckets.

Before diving into the technical aspects, let's take a look at the application's interface and its overall functionality. The application features two tabs. The first tab is called "Browser," which allows users to browse through the existing buckets and explore the data contained within them.

### Browser
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l2jsw77fi3dsaffzdj1o.png)

### Uploader
In the second tab, users can upload data into a selected bucket. This feature allows them to choose a specific bucket and then upload their desired data into it.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9sungepl3wkozp5yun8c.png)

To understand how this application is built, the user interface (UI) and its functional behavior are developed using ToolJet's UI components and their properties. On the other hand, the operations related to Amazon S3 are facilitated through the AWS S3 integration provided by ToolJet. This integration allows the application to interact with Amazon S3 and perform specific actions. For this tutorial, three specific S3 operations

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9cc4uiy6e9zgi19c7uqw.png)

1. "List Bucket": This operation enables the application to retrieve a list of all available buckets in the Amazon S3 account.
2. "List Objects in Bucket": With this operation, the app can fetch the data inside a selected bucket, displaying its contents to the user in the "Browser" tab.
3. "Upload Object": The "Upload Object" operation allows users to select a bucket and then upload their chosen data into that bucket using the functionality available in the second tab of the application.

For the purpose of this tutorial, we have limited the operations to only three; however, it's worth mentioning that the AWS S3 integration offers a wide range of other operations as well. You can explore these additional operations and incorporate them into the application to build any required features beyond the tutorial's scope.

Create a ToolJet Application
To kickstart, let's guide you through creating a new ToolJet application. Whether you are using the cloud-based version of ToolJet or the self-hosted version, the steps are straightforward.

1. Sign up or Sign in: Visit tooljet.com and sign up for a free account if you don't have one. If you already have an account, sign in.
2. Dashboard: After signing in, you will be taken to the ToolJet dashboard. Here, you will find an overview of your existing applications and access to other functionalities.
3. Create a New App: To create a new application, click on the "Create New App" button, which will take you to the 'Application Builder'.
4. Name the application: You can name the application of your choice from the top left corner of the application builder; we can call it "Inventory and Orders Manager."

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zuzfk3t669ho2v4gy8cg.png)

### Connect to AWS S3
To perform all the operations from ToolJet to S3, the first step is to configure and establish the connection with the data source. Here's how you can do it:

1. Return to the ToolJet Dashboard.
2. From the left sidebar, navigate to "Global Datasources."
3. Click on "Add new Datasource."
4. In the gallery of data sources, search for "AWS S3" and select it.
5. Fill in the required details and test the connection before saving it. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b79v0487z4liihd4dq3x.png)

### Aspects of the Application Builder
Let's explore the major areas of the Application Builder that will ease your development process with ToolJet.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aml8osct3n0bzgnmqanq.png)

**1. Canvas**: Canvas is your playground for building your application's user interface (UI). Here, you can visually design and arrange the components of your application's interface. Drag and drop components onto Canvas to create a seamless and user-friendly UI for your apps.
**2. Components Manager**: Located on the right side of the Application Builder, the Components Manager provides you with a comprehensive list of components you can utilize in your application. These pre-built components serve various purposes, such as buttons, forms, tables, etc. With a wide range of components, you can quickly assemble a powerful and visually appealing UI for your app.
**3. Query Panel**: The expandable Query Panel is at the bottom of the Application Builder. This panel plays a crucial role in connecting your application to data sources. It allows you to list and access the connected data sources, seamlessly integrating your Google Sheets data and other data sources. By selecting a data source from the Query Panel, you can create queries to perform specific operations and retrieve data dynamically.
**4. Left sidebar**: The Left Sidebar provides convenient access to features such as creating and managing pages, inspecting components, and the debugger for efficient development and debugging of applications.

Now that you are familiar with the Application Builder, let's dive deeper into each area and explore how you can leverage its features to build the application from scratch.

## Build the Application.

Now that we have explored the ToolJet Application Builder, it's time to dive into building the application step by step. As you know, this app consists of two tabs, so let's begin the development process by creating the "Browser" tab first. We'll focus on implementing the functionality that allows users to browse through the existing buckets and explore the data inside them. Let's get started!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1fd4s15zie3zf02534bx.png)

As a first step, let's set up the navbar for the application. To do this, we'll be using the "container" component, which will serve as the navbar. You can find the "container" component in the components list, and then simply drag and drop it onto the canvas. Once placed, arrange it at the top of the page to ensure it functions as a proper navbar.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yxvf2oxiiwzxzpaffw3e.png)

Next, let's customize the appearance of the navbar. You can choose any color you prefer, or you can use the hash code `#2C3748` to match the color shown in the image. To set the color, click on the container component and navigate to the "Styles" tab in the components manager on the right side. Then, update the value of the "Background Color" field to your desired color.

Now, let's add a title to the navbar. Search for the "text" component in the components list and add it on top of the current container. To update the default text of the component, go to its properties and modify the value of the "Text" field to "AWS S3 File Browser" or any other title you prefer.

Similarly, for the logout icon on the right side of the navbar, you can use the "icon" component with "IconLogout" as the value for the "Icon" field in the component properties.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hcvv1nscmj8f1b6vnn78.png)

Now that the UI for the Navbar is complete, there is one more functional aspect to address: making the logout icon operational. To achieve this, follow these steps:

1. Click on the logout icon component to select it.
2. In the component properties, locate the "Events" section and expand it.
3. Click on the "+ Add handler" button to add a new event handler.
4. Set the following values for the event handler:
- Event: "On click"
- Action: "Logout"

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hkljxkbabbwba0j5v13t.png)

By setting up the event handler in this way, when a user clicks on the logout icon, the currently logged-in user will be signed out and need to log in again to access the application.

With this implementation, the logout functionality will be fully operational, and users can securely log out from the application.

To accommodate both the 'Browser' and 'Uploader' sections of the application, we will utilize a Tabs component. Let's add the Tabs component to the canvas and center it.

1. Click on the Tabs component and access its properties.
2. Update the 'tabs' field value to the following:

```
{[
  { title: 'Browser', id: '0' },
  { title: 'Uploader', id: '1' }
]}
```

This configuration will ensure that the Tabs component displays the two required tabs, one for the 'Browser' section and the other for the 'Uploader' section. Additionally, you can remove any default components within the Tabs component to create a clean slate and set the "Highlight Colour" from Styles to #ec912dff  for further customization.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lfheqd3bdm2zippy98ge.png)

### Building the Browser Tab

In the 'Browser' tab, we will be working with two tables. The first table will list all available buckets, and the second table will display all the objects within a selected bucket.

Let's start by adding two tables, table1 and table2, to the tab component. Adjust the leftmost table (table1) to display only one column by configuring its properties accordingly. Then, arrange the other table (table2) to the right of table1.

For table1, we will customize it by turning off all options in the properties except for the 'Show search box' field. Additionally, set the table's border radius to '5' from the 'Styles' tab of the components manager.

Similarly, for table2, we can turn off all options, while keeping the 'Show search box' enabled to help with data search once the table is loaded.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5bxiz4xc2kd8d657scki.png)

Above table2, let's add an "Input" component along with two buttons. One button will be used for searching, and the other button, placed to the right, will be labeled "Uploader."

By implementing these steps, the 'Browser' tab will be visually organized, with table1 displaying the available buckets, table2 showing the objects within the selected bucket, and the corresponding search and uploader functionalities appropriately positioned above the second table.

### Creating the S3 queries
Now, let's add functionality to the UI by creating our first query, which will enable us to fetch all the buckets from the S3 data source.

To get started, open the query panel by pulling it up from the bottom of the screen. Next, click on the '+ Add' button, or you can directly choose the previously connected S3 data source from the available options.

Once you select the data source, a new window will appear in the query panel. Here, you can give the query a name, such as 'getBuckets,' and choose the operation 'List buckets.' Then, click on the 'Preview' button to test a sample request and hit "Create" to save it.

> Note: By enabling "Run this query on application load," your queries will automatically execute as the app loads. This means that the necessary data will be fetched and displayed without any additional user input. It helps ensure that the app starts with the most up-to-date information.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/amiipfzhe8j567qx5r4e.png)

With this query in place, we will be able to fetch a list of all the buckets, which is needed to populate table1 in the 'Browser' tab.

To connect the query with the table1 component, follow these simple steps:

1. Click on the table1 component to select it, and then navigate to its properties.
2. In the properties section, find the "Table data" field and replace its current value with `{{queries.getBuckets.data.Buckets}}` . This will establish the connection between the query and the component, resulting in the table being populated with the data retrieved from the 'getBuckets' query.
3. If necessary, you can further customize the table by removing any unnecessary columns, leaving only the "Buckets" column to display the names of the available buckets.

With these adjustments, table1 will dynamically display the list of available buckets, we can similarly do the same for table2 when the query for fetching objects of the selected bucket is ready.

To bring all the objects from a selected bucket in table1 to table2, follow these steps:

1. Create a new query named "getObjects" and select the operation "List objects in a bucket". It's essential to dynamically fill the value of the field "Bucket" by selecting a row in table1. To do this, insert `{{components.table1.selectedRow.Name}}` . Additionally, set the maxkeys value to 1000.
2. After creating the query, click on a row in table1 and click "preview" to test the query. Save it by clicking on the "Create" button.
3. Now, just like we connected the "getBuckets" query to table1, let's connect the "getObjects" query to table2. Update the "Table data" property of table2 to `{{queries.getObjects.data.Contents}}` .

As part of the desired functionality, we want to update `table2` every time a new row is clicked in `table1`. To achieve this, go to the properties of table1 and add an event handler with the following settings:

- Event: Row clicked
- Action: Run query
- Query: getObjects

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c8jxvzm7wnbcyhymicqu.png)

With these changes, the "getObjects" query will now be executed and populate table2 every time a new row is selected in table1.

With these steps, both tables in the "Browser" tab are now fully functional. Users can make use of the components' search feature to easily find specific items. Additionally, there are opportunities to implement custom search functionality for the TextInput field above table2, providing even more search capabilities.

Regarding the "Upload files" button, its purpose is to take users to the "Uploader" tab when clicked. To achieve this, you can add an event handler to the button from its properties:

- Event: On Click
- Action: Control component
- Component: tabs1
- Action: Set current tab
- ID: 1

By implementing this event handler, the "Upload files" button will successfully navigate users to the "Uploader" tab, where we will explore how to upload files to a selected bucket.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bq4m6ct4thgyymgssxyh.png)

## Building the Uploader Tab
In the 'Uploader' tab, we need to include multiple fields that will take inputs such as the bucket name, file name, and the file to be uploaded. To build the UI, we can use the components shown in the image, and since the 'Browser' tab is already set up, arranging these components will be straightforward.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hgeqngecxeeo69rsgvas.png)

For the Dropdown component, we want to list all the bucket names as options. To achieve this, we can set the option values and option labels to `{{queries.getBuckets.data.Buckets.map(item => item.Name)}}` . This will dynamically populate the dropdown options with all the bucket names retrieved from the 'getBuckets' query. Additionally, we can set the Default option to `{{components.table1.selectedRow.Name}}` , which will set the dropdown's default value to the selected row of table1 in the 'Browser' tab.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xuzxjk44565z6qtds5fw.png)

### Creating the S3 queries
To enable file uploading to the selected S3 bucket, we will create a new query called 'uploadObject' by following these steps:

1. Click on '+ Add' in the query panel and select the S3 data source. Name the query 'uploadObject' and choose the 'Upload object' operation. This will open a window requesting details of the file to be uploaded.

Dynamically fill the query fields as follows:

- Bucket: `{{components.table2.selectedRow.Name}}`
- Key: `{{components.textinput2.value}}`
- Content Type: `{{components.filepicker1.file[0].type}}`
- Upload Data: `{{components.filepicker1.file[0].dataURL}}`


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ejc9yv8dexelf8en99y.png)

Please note that the IDs of the components in the interpolation text may differ based on your component naming.

1. To test the query, you can add some dummy data to the fields, click 'Preview,' and then 'Create' to save the query.
2. To trigger this query on the 'Upload' button click, you can add an event handler that runs the 'uploadObject' query upon clicking the button.

With these steps, you have successfully built an application that allows you to browse through S3 buckets and perform file uploads. While the tutorial's scope is limited to these features, the S3 integration offers a wide range of operations that you can utilize to extend the application's functionality according to specific requirements.

## What's next

To continue your journey and explore more possibilities with ToolJet, we encourage you to visit and try out our further tutorials here at blog.tooljet.com. Our blog is filled with tutorials, guides, and helpful resources that can further enhance your knowledge and help you unlock the full potential of ToolJet.

In addition to the blog, we also recommend referring to our comprehensive documentation available at [docs.tooljet.com](https://docs.tooljet.com). The documentation covers a wide range of topics, including detailed explanations of components, advanced query techniques etc.

Furthermore, we invite you to join our vibrant community on our [Slack workspace](https://tooljet.com/slack). By joining our community, you can connect with other active ToolJet users, share your experiences, and seek assistance when needed.

Once again, congratulations on your achievements so far! We sincerely thank you for reading this tutorial and choosing ToolJet for your application development needs. We hope this tutorial has provided you with valuable insights and empowered you to build powerful web applications with ease.

We look forward to seeing what you create next with ToolJet. Happy building!