<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Shubhendra Singh Chauhan</title>
    <description>The latest articles on Forem by Shubhendra Singh Chauhan (@camelcaseguy).</description>
    <link>https://forem.com/camelcaseguy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F109823%2Fb91b8a34-cb9b-4f8e-b151-34a1d5b5c3ba.jpeg</url>
      <title>Forem: Shubhendra Singh Chauhan</title>
      <link>https://forem.com/camelcaseguy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/camelcaseguy"/>
    <language>en</language>
    <item>
      <title>Supercharge Your Web Automation with BrowserQL: Logging in and Scraping Private Data Seamlessly</title>
      <dc:creator>Shubhendra Singh Chauhan</dc:creator>
      <pubDate>Sun, 27 Apr 2025 22:23:36 +0000</pubDate>
      <link>https://forem.com/camelcaseguy/supercharge-your-web-automation-with-browserql-logging-in-and-scraping-private-data-seamlessly-59i2</link>
      <guid>https://forem.com/camelcaseguy/supercharge-your-web-automation-with-browserql-logging-in-and-scraping-private-data-seamlessly-59i2</guid>
      <description>&lt;p&gt;Scraping data behind a login is often one of the hardest parts of browser automation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Traditional tools&lt;/strong&gt; like Puppeteer or Playwright can do it — but they require &lt;strong&gt;heavy setup&lt;/strong&gt;, &lt;strong&gt;CAPTCHA bypass tricks&lt;/strong&gt;, and &lt;strong&gt;constant maintenance&lt;/strong&gt; to handle anti-bot defenses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browserless.io&lt;/strong&gt; changes the game with &lt;a href="https://browserless.io/" rel="noopener noreferrer"&gt;&lt;strong&gt;BrowserQL&lt;/strong&gt;&lt;/a&gt; — their GraphQL-based automation API, designed to make stealth-first browser control easier than ever.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this guide, we’ll:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log in to &lt;a href="https://news.ycombinator.com" rel="noopener noreferrer"&gt;Hacker News&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Access the user's private profile page&lt;/li&gt;
&lt;li&gt;Extract hidden data (the user's email address)&lt;/li&gt;
&lt;li&gt;Learn why BrowserQL makes this process effortless compared to traditional approaches&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ And we’ll do it with clean Node.js code and just a few simple mutations.&lt;/p&gt;

&lt;p&gt;Find the entire code in this &lt;a href="https://github.com/withshubh/login-and-scrape" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Why Browserless and BrowserQL?
&lt;/h2&gt;

&lt;p&gt;Before we dive into code, let’s understand why Browserless is a major upgrade for web automation:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem with Traditional Automation&lt;/th&gt;
&lt;th&gt;How-  Browserless/BrowserQL Solves It&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fingerprinting (easily detected bots)&lt;/td&gt;
&lt;td&gt;Browserless automatically applies human-like fingerprints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proxies and session management&lt;/td&gt;
&lt;td&gt;Built-in session handling and proxy support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complex async code to wait for pages&lt;/td&gt;
&lt;td&gt;GraphQL-style mutations like &lt;code&gt;waitForNavigation&lt;/code&gt; and &lt;code&gt;goto&lt;/code&gt; handle waits intuitively&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heavy setup and browser maintenance&lt;/td&gt;
&lt;td&gt;Fully cloud-hosted; no local browsers needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Managing CAPTCHAs and consent modals&lt;/td&gt;
&lt;td&gt;BrowserQL options handle consent modals, stealth scripts minimize CAPTCHA triggers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Browserless essentially &lt;strong&gt;lets you focus on your business logic&lt;/strong&gt;, not fighting web defenses.&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;No browser binaries.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;No network headaches.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;No bot detection flags.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hv84hav2r0985ucwb8v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hv84hav2r0985ucwb8v.png" alt="browserless-loggedin" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Account on &lt;a href="//Browserless.io"&gt;Browserless.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Node&lt;/code&gt; &amp;amp; &lt;code&gt;npm&lt;/code&gt; installed locally&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The BrowserQL Query: Logging In and Scraping
&lt;/h2&gt;

&lt;p&gt;BrowserQL uses a &lt;strong&gt;GraphQL-style&lt;/strong&gt; syntax where every interaction with the browser is expressed as a &lt;strong&gt;mutation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Our flow will involve the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to Hacker News login page&lt;/li&gt;
&lt;li&gt;Type the username and password&lt;/li&gt;
&lt;li&gt;Click the login button&lt;/li&gt;
&lt;li&gt;Wait for navigation to confirm login&lt;/li&gt;
&lt;li&gt;Navigate to the private profile page&lt;/li&gt;
&lt;li&gt;Scrape the email field from the form&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s the BrowserQL mutation we’ll use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="k"&gt;mutation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LoginAndScrape&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://news.ycombinator.com/login"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;networkIdle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;enterUsername&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yourUsername"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"input[name='acct']"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;enterPassword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yourPassword"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"input[name='pw']"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;clickLogin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"input[type='submit'][value='login']"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;afterLogin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;waitForNavigation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;postLoginScrape&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://news.ycombinator.com/user?id=yourUsername"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;networkIdle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;emailAddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mapSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"input[name='email']"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To test this visually, we will run this inside the &lt;strong&gt;BrowserQL IDE&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Login&lt;/strong&gt; to Browserless.io&lt;/li&gt;
&lt;li&gt;Select the &lt;strong&gt;BrowserQL Editor&lt;/strong&gt; from the left navigation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy-paste&lt;/strong&gt; the above code and update the credentials&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡Once tested on BroswerQL IDE, you can use the &lt;code&gt;Export Query as Code&lt;/code&gt; feature to turn any of your queries into a number of available coding languages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn5oeeg4hvpyx5hfwieoi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn5oeeg4hvpyx5hfwieoi.png" alt="bql-editor" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How BrowserQL Mutations Work
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mutation&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;goto&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Navigates to a page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;type&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Types into an input field&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;click&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clicks a button&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;waitForNavigation&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Waits until page navigation completes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;mapSelector&lt;/code&gt; + &lt;code&gt;attribute&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Extracts data from HTML elements&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: While &lt;code&gt;text()&lt;/code&gt; mutation extracts visible text, input fields (like email forms) require fetching the value attribute instead.&lt;br&gt;
That's why we use mapSelector + attribute(name: "value") to scrape the email address cleanly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can find the list of all the mutations on &lt;a href="https://docs.browserless.io/bql-schema/operations/mutations/goto" rel="noopener noreferrer"&gt;Browserless Docs&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting Up the Project
&lt;/h2&gt;

&lt;p&gt;Let’s get started with a simple Node.js project.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Initialize a new project and install dependencies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;node-fetch dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;node-fetch:&lt;/strong&gt; To make API requests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;dotenv:&lt;/strong&gt; To securely manage API tokens&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. Create a &lt;code&gt;.env&lt;/code&gt; file for your API key
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Never hardcode sensitive information&lt;/strong&gt; like API tokens.&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;.env&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BROWSERLESS_TOKEN=your-browserless-api-token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And add &lt;code&gt;.env&lt;/code&gt; to your &lt;code&gt;.gitignore&lt;/code&gt; file to avoid committing secrets.&lt;/p&gt;




&lt;h2&gt;
  
  
  NodeJS Code:
&lt;/h2&gt;

&lt;p&gt;Now let’s export the code from the BrowserQL IDE:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open BrowserQL IDE&lt;/li&gt;
&lt;li&gt;Select the &lt;code&gt;Export query as Code&lt;/code&gt; option on right side of the editor&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Javascript(fetch)&lt;/code&gt; from the list of available languages&lt;/li&gt;
&lt;li&gt;click on the &lt;code&gt;copy&lt;/code&gt; icon on top of the code-block&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The copied code will include the hardcoded API token. You will need to remove the token from the code and put it in the &lt;code&gt;.env&lt;/code&gt; file. You can also find the API Token on the dashboard of Browserless.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Add the following lines on top of the copied code:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node-fetch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;dotenv&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TOKEN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Your final code will look like this:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node-fetch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;dotenv&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;endpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://production-sfo.browserless.io/chrome/bql&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TOKEN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;optionsString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;blockConsentModals=true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
mutation LoginAndScrape {
  goto(url: "https://news.ycombinator.com/login", waitUntil: networkIdle) {
    status
  }

  enterUsername: type(
    text: "yourUsername", 
    selector: "input[name='acct']"
  ) {
    time
  }

  enterPassword: type(
    text: "yourPassword", 
    selector: "input[name='pw']"
  ) {
    time
  }

  clickLogin: click(
    selector: "input[type='submit'][value='login']"
  ) {
    time
  }

  afterLogin: waitForNavigation {
    url
    status
  }

  postLoginScrape: goto(
    url: "https://news.ycombinator.com/user?id=yourUsername",
    waitUntil: networkIdle
  ) {
    status
  }

emailAddress: mapSelector(selector: "input[name='email']") {
  email: attribute(name: "value") {
    value
  }
}
}

    `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;operationName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LoginAndScrape&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;?token=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;optionsString&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Browserless handles the entire browser session, fingerprinting, navigation, and anti-bot measures behind the scenes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Expected Output
&lt;/h2&gt;

&lt;p&gt;Running the script returns a clean JSON like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"emailAddress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"username@email.com"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldhitjznffpynvru3857.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldhitjznffpynvru3857.png" alt="response" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why BrowserQL Shines Here
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Browserless Advantage&lt;/th&gt;
&lt;th&gt;Impact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cloud-hosted stealth browsers&lt;/td&gt;
&lt;td&gt;No local installation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Built-in human-like behavior&lt;/td&gt;
&lt;td&gt;Bypass simple bot detection automatically&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Consent modals auto-accepted&lt;/td&gt;
&lt;td&gt;No annoying pop-ups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GraphQL language&lt;/td&gt;
&lt;td&gt;No need to learn complex browser APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Session management handled&lt;/td&gt;
&lt;td&gt;Clean, lightweight scripts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;✅ In 30 lines, you’ve built a real-world login automation and data extraction workflow!&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;BrowserQL isn't just a new API — it’s a &lt;strong&gt;new way of thinking about browser automation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stealth-first&lt;/strong&gt; by design&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud-native&lt;/strong&gt; from day one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intuitive&lt;/strong&gt; like GraphQL, not procedural coding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to stop worrying about fingerprints, proxies, CAPTCHAs, and flaky browsers —&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Browserless and BrowserQL are your secret weapons.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Try BrowserQL Yourself
&lt;/h2&gt;

&lt;p&gt;You can start experimenting with BrowserQL today:&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://browserless.io/" rel="noopener noreferrer"&gt;Create your free Browserless account here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>opensource</category>
      <category>javascript</category>
      <category>testing</category>
    </item>
    <item>
      <title>Managing Multiple Git Profiles with Ease: Introducing `gguser`</title>
      <dc:creator>Shubhendra Singh Chauhan</dc:creator>
      <pubDate>Fri, 28 Feb 2025 20:48:52 +0000</pubDate>
      <link>https://forem.com/camelcaseguy/managing-multiple-git-profiles-with-ease-introducing-gguser-3lcg</link>
      <guid>https://forem.com/camelcaseguy/managing-multiple-git-profiles-with-ease-introducing-gguser-3lcg</guid>
      <description>&lt;p&gt;If you're a developer juggling between work projects, personal side projects, and maybe even some open-source contributions, you're likely familiar with a common frustration—&lt;strong&gt;managing multiple Git identities on the same machine&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine this scenario: You commit changes to your personal project and push them to GitHub, only to realize that your work email is attached to the commit. Or worse, you accidentally push a work-related change using your personal GitHub account. Fixing this means manually updating your Git config each time you switch contexts.&lt;/p&gt;

&lt;p&gt;For years, developers have resorted to running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.name &lt;span class="s2"&gt;"Your Name"&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.email &lt;span class="s2"&gt;"your.email@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this is tedious and error-prone. What if there was a better way?&lt;/p&gt;

&lt;h2&gt;
  
  
  Meet &lt;code&gt;gguser&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;gguser&lt;/code&gt; is a simple yet powerful CLI tool designed to &lt;strong&gt;seamlessly switch between multiple Git user profiles&lt;/strong&gt;. Whether you're switching between work, personal, or open-source accounts, &lt;code&gt;gguser&lt;/code&gt; makes the process effortless.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 &lt;strong&gt;Installing &lt;code&gt;gguser&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Installing &lt;code&gt;gguser&lt;/code&gt; is quick and easy. Simply run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; gguser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you have &lt;code&gt;gguser&lt;/code&gt; available globally, ready to manage your Git profiles.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 &lt;strong&gt;How to Use &lt;code&gt;gguser&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1️⃣ &lt;strong&gt;Adding Git Profiles&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Before switching between Git users, you need to define them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gguser add &amp;lt;profile_name&amp;gt; &lt;span class="s2"&gt;"&amp;lt;full_name&amp;gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;email&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;ssh_key]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gguser add work &lt;span class="s2"&gt;"Shubhendra Chauhan"&lt;/span&gt; &lt;span class="s2"&gt;"work@company.com"&lt;/span&gt; ~/.ssh/id_ed25520
gguser add personal &lt;span class="s2"&gt;"Shubhendra Singh Chauhan"&lt;/span&gt; &lt;span class="s2"&gt;"personal@email.com"&lt;/span&gt; ~/.ssh/id_ed25521
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the &lt;strong&gt;SSH key is optional&lt;/strong&gt; but useful if you want to authenticate using SSH.&lt;/p&gt;




&lt;h3&gt;
  
  
  2️⃣ &lt;strong&gt;Switching Between Git Profiles&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Interactive Selection&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Instead of remembering profile names, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gguser &lt;span class="k"&gt;select&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see a list of your configured profiles and can simply pick one.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Quick Switching&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;If you already know which profile you want to switch to, just run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gguser &amp;lt;profile_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gguser work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This updates your Git global config instantly.&lt;/p&gt;




&lt;h3&gt;
  
  
  3️⃣ &lt;strong&gt;Checking Your Current Git User&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Ever wondered which Git identity is active? Quickly verify using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gguser now
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will display the currently configured Git user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;👤 Current Git User: Shubhendra Singh Chauhan &amp;lt;personal@email.com&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  4️⃣ &lt;strong&gt;Managing Your Profiles&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Listing All Profiles&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;To see all configured profiles, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gguser list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Removing a Profile&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;No longer need a profile? Remove it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gguser remove &amp;lt;profile_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔗 &lt;strong&gt;Linking a Profile to a Directory&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Many developers work on &lt;strong&gt;different projects that require different Git identities&lt;/strong&gt;. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your &lt;strong&gt;personal&lt;/strong&gt; projects live in &lt;code&gt;~/projects/personal&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Your &lt;strong&gt;work&lt;/strong&gt; projects live in &lt;code&gt;~/projects/work&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of manually switching Git users each time, you can &lt;strong&gt;link a profile to a specific directory&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gguser &lt;span class="nb"&gt;link &lt;/span&gt;work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, whenever you enter that directory, &lt;code&gt;gguser&lt;/code&gt; will automatically use the correct Git profile.&lt;/p&gt;

&lt;p&gt;To unlink:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gguser &lt;span class="nb"&gt;unlink&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔥 &lt;strong&gt;Why &lt;code&gt;gguser&lt;/code&gt; is a Game-Changer&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;✅ &lt;strong&gt;No more accidental commits with the wrong Git identity&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Seamlessly switch between work, personal, and open-source profiles&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Automatic profile selection based on directories&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Easily manage SSH keys&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Developer-friendly CLI with an interactive selection mode&lt;/strong&gt;  &lt;/p&gt;




&lt;h2&gt;
  
  
  💡 &lt;strong&gt;Contribute or Extend &lt;code&gt;gguser&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;gguser&lt;/code&gt; is open-source, and contributions are welcome! If you have ideas for improvements or new features, feel free to submit a pull request. You can check out the repo here:&lt;/p&gt;

&lt;p&gt;🔗 GitHub: &lt;a href="https://github.com/withshubh/gguser" rel="noopener noreferrer"&gt;https://github.com/withshubh/gguser&lt;/a&gt;&lt;br&gt;&lt;br&gt;
📦 NPM: &lt;a href="https://www.npmjs.com/package/gguser" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/gguser&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 &lt;strong&gt;Final Thoughts&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;For developers working with multiple Git accounts, &lt;code&gt;gguser&lt;/code&gt; is a must-have tool. No more wasting time manually updating Git config settings or dealing with incorrect commit histories. Try it out today and simplify your workflow!&lt;/p&gt;

&lt;p&gt;Let me know in the comments how &lt;code&gt;gguser&lt;/code&gt; has helped you! 🚀&lt;/p&gt;

</description>
      <category>git</category>
      <category>cli</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Kubernetes for Beginners: Introduction, Functionality, and Cost</title>
      <dc:creator>Shubhendra Singh Chauhan</dc:creator>
      <pubDate>Sat, 20 Jan 2024 13:05:45 +0000</pubDate>
      <link>https://forem.com/camelcaseguy/kubernetes-for-beginners-introduction-functionality-and-cost-1n68</link>
      <guid>https://forem.com/camelcaseguy/kubernetes-for-beginners-introduction-functionality-and-cost-1n68</guid>
      <description>&lt;p&gt;Are you just starting to learn about Kubernetes, but the technical jargon and complex concepts are making your head spin? Fear not! In this beginner-friendly tutorial, we'll dive into everything you need to know about Kubernetes to kickstart your journey. Whether you're a developer, IT enthusiast, or someone just curious about the world of tech, we'll break down the basics of Kubernetes, explore its functionalities, and even sprinkle in some insights on managing costs associated with it. So, let's get started.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Note: This tutorial assumes a basic familiarity with Docker. If you're new to Docker, consider exploring its fundamentals before diving into this content for a smoother learning experience.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Functionality&lt;/li&gt;
&lt;li&gt;
Cost

&lt;ul&gt;
&lt;li&gt;Cost associated with k8 clusters&lt;/li&gt;
&lt;li&gt;Optimizing cost&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Introduction &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Let's first take a look at the definition of Kubernetes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Kubernetes, also known as K8s, is an open-source container orchestration tool developed by Google to help you manage containerized/dockerized applications supporting multiple deployment environments like On-premise, cloud, or virtual machines.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In simple words, imagine you have a bunch of different programs, each like a little worker doing a specific job. Now, Kubernetes is like the smart manager that keeps an eye on all these workers (we call them containers) and makes sure they're doing their tasks correctly.&lt;/p&gt;

&lt;p&gt;Think of these containers as small, portable boxes that contain everything a program needs to work smoothly. They could be on your computer, in the cloud, or on some virtual machines – it doesn't matter. Kubernetes helps you manage and organize these containers so that your programs run smoothly no matter where they are.&lt;/p&gt;

&lt;h3&gt;
  
  
  Functionality &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Now, we will learn about the functionalities of Kubernetes using an analogy:&lt;/p&gt;

&lt;p&gt;Imagine you have a bakery with a superstar baker (your website) making delicious cakes (information) stored in a special box (Docker container). Business is booming, and lots of people are coming in to buy cakes. But, oh no, the baker is getting overwhelmed, and sometimes the cakes don't come out right.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Issue:&lt;/strong&gt; Too many customers, and the baker (Docker container) is struggling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution:&lt;/strong&gt; You decide to set up another baker in a different kitchen (server) to share the workload.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Functionality: Horizontal Scaling&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Explanation:&lt;/strong&gt; In the digital world, we call this "Horizontal Scaling," where we duplicate our bakers (pods) to handle more customers (traffic).&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;This helps for a while, but your bakery becomes so famous that you're flooded with customers, and now you need even more bakers and kitchens. It's a lot of work, and you can't update the cake recipes without a headache.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Issue:&lt;/strong&gt; The bakery is getting extremely popular, and you need more bakers and kitchens (servers).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution:&lt;/strong&gt; You set up another 20+ servers (just to be sure this time), which all need Docker containers and some extra load balancers to help manage the bandwidth distribution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Functionality: Load Balancing and Efficient Resource Management&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Explanation:&lt;/strong&gt; Now, you're practicing "Load Balancing" to make sure customers are evenly distributed between your servers, and you're also efficiently managing resources to handle the increased workload.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Now, imagine if you had a magical organizer (Kubernetes). Right from the start, when you had just one or two bakers, this organizer could automatically duplicate them whenever you needed. In this magical world, each baker (Docker container) is called a 'pod,' and the organizer knows exactly how many bakers you want (worker nodes).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Functionality: Pod Creation and Auto-scaling&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Explanation:&lt;/strong&gt; The magical organizer is Kubernetes, creating and managing 'pods' (containers) and automatically adjusting their numbers based on your needs. It's like having a dynamic baking team that grows or shrinks as the demand changes.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;You simply tell the organizer (Kubernetes master) how many pods (bakers) you need, and it takes care of distributing the workload among them, making sure no baker is overworked or underworked. Plus, you can easily update your recipes (website) without breaking a sweat.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Functionality: Workload Distribution and Rolling Updates&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Explanation:&lt;/strong&gt; Kubernetes master efficiently distributes the workload among pods, ensuring each one is handling its fair share. When you update your recipes (website), it's like having a smooth "Rolling Update" without disrupting the entire bakery operation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's like having a baking manager who automatically handles everything, ensuring your bakery runs smoothly, no matter how many customers (visitors) show up. Smart, isn't it? 🍰✨&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Functionality: Exposing the Bakery to the World&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So these pods (bakers) that are created, and the cakes (website) that are inside them, all have their own addresses. Great, they are all accessible to the outside world, and each version of your bakery can be reached by the public and by you if you want to edit anything.&lt;/p&gt;

&lt;p&gt;Wait...how can they be exposed if they are in a pod? Well, it’s one of the powerful features of Kubernetes.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Functionality: Service and Load Balancing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Explanation:&lt;/strong&gt; For the outside world to view your bakery, you need to expose the pods to the network. If you tell it to, Kubernetes will spin up something called a 'Service,' acting like a diligent front-of-house staff member to make sure that none of the bakers (pods) are getting too much traffic and risking a 'crash zone.'&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Functionality: Precision Load Balancing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Explanation:&lt;/strong&gt; Unlike a usual front-of-house staff member (load balancer), Kubernetes Service balances the load by baker ID (pod ID), ensuring that you can control everything with a lot more precision. It's like making sure each baker is handling customers according to their individual capacity.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Functionality: Cloud Provider Load Balancer&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Explanation:&lt;/strong&gt; To top it all off, Kubernetes creates a load balancer in your cloud provider. This means that you update your bakery in one place, and like magic, the changes are reflected everywhere. It's like having a head chef who updates the menu centrally, and all the kitchens automatically get the latest recipes. Mind-blowing, isn't it? 🤯&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;From the above analogy we can conclude the following benefits of using Kubernetes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Assures high availability with zero downtime&lt;/li&gt;
&lt;li&gt;Highly performant and scalable&lt;/li&gt;
&lt;li&gt;Reliable infrastructure to support data backup and recovery&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Bonus: A video that explains Kubernetes&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/4ht22ReBjno"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Over the past decade, migrating to the public cloud and adopting continuous delivery has enabled developers to move faster than ever before. accelerating their time to market from weeks to on-demand using self-service capabilities. Today developers consume the cloud like they consume coffee but they never get to see the real cost, resulting in the CFOs and finance teams receiving the bill every 30 days with little to no context. The problem today is that developers lack basic visibility into which apps or microservices are consuming cloud resources and costs. Over-provisioned infrastructure, deserted environments, zombie nodes, or even under-utilized clusters can all be cost wildfires but they go unnoticed until someone finally picks up the bill. In a world where developers are scrambling to determine the root cause of cloud cost, Tagging has become the new scripting. However, tagging cloud infrastructure with labels is a time-consuming mind-numbing, and never-ending exercise that at best is only 75% accurate in an ever-changing world.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cost associated with k8 clusters &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;The cost associated with Kubernetes (K8s) clusters can vary based on several factors, including the cloud provider you choose, the type and size of instances you use, the storage requirements, network usage, and any additional services or features you employ. Here are some key factors that contribute to the cost of running Kubernetes clusters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Compute Resources (Instances):&lt;/strong&gt; The cost of the virtual machines or instances used to run your Kubernetes nodes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage:&lt;/strong&gt; The cost of persistent storage for your data within the cluster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Traffic:&lt;/strong&gt; Charges related to data transfer between nodes, load balancers, and services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managed Services:&lt;/strong&gt; If using a managed Kubernetes service from a cloud provider, there may be additional costs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load Balancers:&lt;/strong&gt; Charges for using load balancing services to distribute traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geographical Location:&lt;/strong&gt; The cost of resources can vary based on the geographical region in which your Kubernetes clusters are deployed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhegmpz2ltugsoarcjvd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhegmpz2ltugsoarcjvd.png" alt="K8" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Optimizing cost &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Let’s look at some of the ways through which the cost can be optimized focusing on primary cost factors associated with K8 clusters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Compute Resources (Instances):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Right-size Instances:&lt;/strong&gt; Choose instances that match your actual workload requirements to avoid overprovisioning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-scaling:&lt;/strong&gt; Implement auto-scaling to dynamically adjust the number of instances based on demand.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Optimize Storage:&lt;/strong&gt; Choose the right type of storage (e.g., standard, SSD) based on your performance needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Lifecycle Policies:&lt;/strong&gt; Implement automated policies for managing data lifecycle, including retention and deletion.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Traffic:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimize Data Transfer:&lt;/strong&gt; Optimize communication between services and regions to reduce data transfer costs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Delivery Networks (CDNs):&lt;/strong&gt; Use CDNs for static assets to lower data transfer costs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managed Services:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Evaluate Costs:&lt;/strong&gt; Compare the costs of using managed Kubernetes services vs. self-managed clusters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose Efficient Services:&lt;/strong&gt; Use only the managed services that are necessary for your application.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load Balancers:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use Efficiently:&lt;/strong&gt; Optimize the use of load balancers and consider alternatives for specific use cases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evaluate Traffic Patterns:&lt;/strong&gt; Understand your application's traffic patterns to provision load balancers appropriately.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geographical Location:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Select Regions Wisely:&lt;/strong&gt; Choose regions based on cost considerations and the geographic distribution of your user base.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consider Multi-Region Strategies:&lt;/strong&gt; Explore multi-region deployments for redundancy and cost optimization.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These tips specifically target the major cost factors associated with running Kubernetes clusters. By implementing these strategies and integrating tools, you can optimize your spending on compute resources, storage, network traffic, managed services, load balancers, and geographical considerations. Regularly review and adjust your configurations based on changing requirements to ensure ongoing cost efficiency.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>beginners</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Threads or Twitter?</title>
      <dc:creator>Shubhendra Singh Chauhan</dc:creator>
      <pubDate>Thu, 06 Jul 2023 18:53:29 +0000</pubDate>
      <link>https://forem.com/camelcaseguy/threads-or-twitter-5991</link>
      <guid>https://forem.com/camelcaseguy/threads-or-twitter-5991</guid>
      <description>&lt;h2&gt;
  
  
  Threads vs. Twitter: What are the Differences?
&lt;/h2&gt;

&lt;p&gt;Threads and Twitter are both social media platforms that allow users to share short messages with their followers. However, there are some key differences between the two platforms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Threads
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Threads is a standalone app that is owned by Meta (formerly Facebook).&lt;/li&gt;
&lt;li&gt;Threads is designed for sharing more personal and intimate content with close friends and family.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Twitter
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Twitter is a larger social media platform with over 330 million active users.&lt;/li&gt;
&lt;li&gt;Twitter is designed for sharing a wider range of content, including news, events, and personal thoughts.&lt;/li&gt;
&lt;li&gt;Twitter messages are not ephemeral, meaning that they remain on the platform indefinitely.&lt;/li&gt;
&lt;li&gt;Twitter includes features like hashtags, @mentions, and retweets.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Which Platform is Right for You?
&lt;/h2&gt;

&lt;p&gt;The best platform for you will depend on your individual needs and preferences. If you are looking for a platform to share personal and intimate content with close friends and family, then Threads is a good option. If you are looking for a platform to share a wider range of content with a larger audience, then Twitter is a good option.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here is a table that summarises the key differences between Threads and Twitter:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Threads&lt;/th&gt;
&lt;th&gt;Twitter&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Platform&lt;/td&gt;
&lt;td&gt;Standalone app&lt;/td&gt;
&lt;td&gt;Website and app&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Target audience&lt;/td&gt;
&lt;td&gt;Close friends and family&lt;/td&gt;
&lt;td&gt;Wider audience&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Characters limit&lt;/td&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;td&gt;280&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repost&lt;/td&gt;
&lt;td&gt;Can't see numbers, only notifications for repost&lt;/td&gt;
&lt;td&gt;Can see numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hashtags&lt;/td&gt;
&lt;td&gt;not available&lt;/td&gt;
&lt;td&gt;available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@mentions&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drafts&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What do you think? Which platform would you prefer?
&lt;/h2&gt;

&lt;p&gt;I would love to hear your thoughts in the comments below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8ul0xqdd9mg87eo2sa7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8ul0xqdd9mg87eo2sa7.gif" alt="cat" width="360" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>socialmedia</category>
      <category>news</category>
    </item>
    <item>
      <title>Building an efficient email marketing application with ChatGPT, ToolJet, and PostgreSQL</title>
      <dc:creator>Shubhendra Singh Chauhan</dc:creator>
      <pubDate>Tue, 06 Jun 2023 11:44:47 +0000</pubDate>
      <link>https://forem.com/tooljet/building-an-efficient-email-marketing-application-with-chatgpt-tooljet-and-postgresql-25g8</link>
      <guid>https://forem.com/tooljet/building-an-efficient-email-marketing-application-with-chatgpt-tooljet-and-postgresql-25g8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In this tutorial, you'll learn how to build an email marketing application using ToolJet, ChatGPT, and PostgreSQL.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The application allows you to add subscribers to your mailing list, group them into categories, and send them newsletters using &lt;a href="https://www.brevo.com/" rel="noopener noreferrer"&gt;Brevo (formerly Sendinblue)&lt;/a&gt;. We'll also use ChatGPT for generating email content. All these features are very easy to integrate with the help of ToolJet.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is ToolJet?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/ToolJet/ToolJet" rel="noopener noreferrer"&gt;ToolJet&lt;/a&gt; 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.&lt;/p&gt;

&lt;p&gt;ToolJet allows you to build applications that use relational and non-relational databases, REST APIs, OpenAI technologies, and cloud storage like &lt;a href="https://cloud.google.com/storage" rel="noopener noreferrer"&gt;Google Cloud Storage&lt;/a&gt;, &lt;a href="https://aws.amazon.com/pm/serv-s3" rel="noopener noreferrer"&gt;AWS S3&lt;/a&gt;, and &lt;a href="https://min.io/" rel="noopener noreferrer"&gt;Minio&lt;/a&gt;. It is an excellent development tool helping individuals, developers, and businesses create and ship products faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before we continue, I need your help? 😔&lt;/strong&gt;&lt;br&gt;
I would be super happy if you could give us a star! And let me also know in the comments section. ❤️&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ToolJet/ToolJet" rel="noopener noreferrer"&gt;https://github.com/ToolJet/ToolJet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nfnzw4wf7oybaclylqd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nfnzw4wf7oybaclylqd.gif" alt="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExZjlhNzRjMWJlYzgyNWZjYjcyOGMxYjJiYjQxOTQzYTU1NTg5YzAzNiZjdD1n/dfbMVqwq8GrC19xSEF/giphy.gif" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up an ElephantSQL (PostgreSQL) database
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.elephantsql.com/" rel="noopener noreferrer"&gt;ElephantSQL&lt;/a&gt; enables us to create a PostgreSQL database on the cloud instead of your local machine. Follow the steps below to create a PostgreSQL database:&lt;/p&gt;

&lt;p&gt;Create an ElephantSQL account &lt;a href="https://customer.elephantsql.com/login" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Add a new database instance. No credit card or billing information is required.&lt;/p&gt;

&lt;p&gt;Once you've created the database instance, your database information is displayed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fisu5h2gyiw3gey077bvk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fisu5h2gyiw3gey077bvk.png" alt="01" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You've successfully created the database needed for this application. Next, let's design the application interface and connect the database to the application.&lt;/p&gt;
&lt;h2&gt;
  
  
  Building the application with ToolJet
&lt;/h2&gt;

&lt;p&gt;Here, you'll learn how to create a ToolJet account and build a fully functional application with ToolJet.&lt;/p&gt;

&lt;p&gt;If you are new to ToolJet, &lt;a href="https://app.tooljet.com/signup" rel="noopener noreferrer"&gt;create an account&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Create a Workspace and a new app called Newsletter Manager.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi21wsyg9lfjf6sbzwtsl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi21wsyg9lfjf6sbzwtsl.png" alt="02" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The application is divided into four pages - the home page, the &lt;code&gt;ViewNewsletter&lt;/code&gt; page, the &lt;code&gt;CreateNewsletter&lt;/code&gt; page, and the &lt;code&gt;SubscribersManager&lt;/code&gt; page. Click on the pages icon on the top left corner to create the three additional pages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8o1bp1i08gt2qufzovoc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8o1bp1i08gt2qufzovoc.png" alt="03" width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftzrwkuw5g0dspy5rcrv5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftzrwkuw5g0dspy5rcrv5.png" alt="04" width="440" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the home page, you can view all the available newsletters and navigate to the &lt;code&gt;SubscribersManager&lt;/code&gt; and &lt;code&gt;CreateNewsletter&lt;/code&gt; pages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqvgvqzv40ppzhvo84le.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqvgvqzv40ppzhvo84le.png" alt="05" width="800" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;ViewNewsletter&lt;/code&gt; page displays the details of a published newsletter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwrc1t5x6r6s6jkz0elpz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwrc1t5x6r6s6jkz0elpz.png" alt="06" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;CreateNewsletter&lt;/code&gt; page enables us to create a newsletter as a draft or publish it by sending it to a group of users.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fodu566aeop9ja2gl9y8o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fodu566aeop9ja2gl9y8o.png" alt="07" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;SubscribersManager&lt;/code&gt; page displays existing subscribers and allows you to add a new subscriber to the list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpy6wvp407c80dz4n1x0d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpy6wvp407c80dz4n1x0d.png" alt="08" width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  The Home page
&lt;/h3&gt;

&lt;p&gt;Here, you'll learn how to build the user interface below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0g2c4r8uzc9ugav2f7pm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0g2c4r8uzc9ugav2f7pm.png" alt="09" width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To create the UI above, you need to add a container element on the canvas that will house all the other UI elements of the application.&lt;br&gt;
Next, drag the Text and Button component from the panel on the right into the container element to create the title and buttons.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgwytmhm53a8p179tlpt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgwytmhm53a8p179tlpt.png" alt="10" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the image above, I added a Tab component below the button and text components. Next, edit the Tab component to contain only the Published and Drafts tab menu by copying the code snippet below into the Tabs input at the right-hand side of the screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{{[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Published&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Drafts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;]}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remove the ToolJet image at the centre of the list and insert the &lt;code&gt;ListView&lt;/code&gt; component into the body of the Tab component. Adjust it until it becomes similar to this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F833t7ucsm8y74602xqk3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F833t7ucsm8y74602xqk3.png" alt="11" width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, add an &lt;code&gt;on click&lt;/code&gt; event on the Subscribers button to navigate users to the &lt;code&gt;SubscribersManager&lt;/code&gt; page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F42m16sft3ssc0i526ni5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F42m16sft3ssc0i526ni5.png" alt="12" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, add an &lt;code&gt;on click&lt;/code&gt; event on the Create button that redirects users to the &lt;code&gt;Create Newsletter&lt;/code&gt; page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fluoc5ea7svdnh6l3a4jd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fluoc5ea7svdnh6l3a4jd.png" alt="13" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The View newsletter page
&lt;/h3&gt;

&lt;p&gt;Change the current page to the &lt;code&gt;ViewNewsletter&lt;/code&gt; page, place a large container on the canvas, and create a UI similar to the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hq2kb6ophloro6fhtr4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hq2kb6ophloro6fhtr4.png" alt="14" width="800" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are three text components - the application's name, title and content, and the Back button. The Title and content texts are placeholders for the title and content of each newsletter. This page allows us to view the contents of any published newsletter.&lt;/p&gt;

&lt;p&gt;Finally, add an &lt;code&gt;on click&lt;/code&gt; event on the Back button to redirect users to the Home page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatgs1umgnxlbr069trgj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatgs1umgnxlbr069trgj.png" alt="15" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Create newsletter page
&lt;/h3&gt;

&lt;p&gt;This page enables you to save and publish a newsletter. It accepts the newsletter's title, email group, and content. You can also use AI-generated content with ChatGPT by providing accurate prompts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj6tjj0v02pdbcwqbo7kl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj6tjj0v02pdbcwqbo7kl.png" alt="16" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Save to Draft&lt;/code&gt; and &lt;code&gt;Send&lt;/code&gt; buttons allow us to save the newsletter or send it to the users' email.&lt;/p&gt;

&lt;p&gt;Finally, redirect users to the home when they click the Back button.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Subscribers manager page
&lt;/h3&gt;

&lt;p&gt;On this page, you can view all the existing subscribers and add a new subscriber to the list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpmu6tzrpebvukx7qkgc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpmu6tzrpebvukx7qkgc.gif" alt="addSubscriber" width="600" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Design the page as shown below. We have the Title and Button components at the top of the page and the Table component displaying the list of subscribers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5mijukli9v31vz3zt00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5mijukli9v31vz3zt00.png" alt="17" width="800" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, add an &lt;code&gt;on click&lt;/code&gt; event on the Add button such that it displays a Modal component that allows you to add the subscriber's details.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftif6paetxn09i0n4xdf4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftif6paetxn09i0n4xdf4.png" alt="18 description" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You've successfully built the user interface for the application. Next, let's add the required functionalities to the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to communicate with a PostgreSQL database in ToolJet
&lt;/h2&gt;

&lt;p&gt;ToolJet allows us to communicate with external resources or create custom functions via a panel known as &lt;a href="https://docs.tooljet.com/docs/app-builder/query-panel" rel="noopener noreferrer"&gt;Query Panel&lt;/a&gt;. In ToolJet, any function that interacts with a database, API, or cloud storage and runs a JavaScript or Python code is called a Query.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frl21nex1iylbrm539da7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frl21nex1iylbrm539da7.png" alt="19 description" width="800" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, you'll learn how to communicate with a PostgreSQL database in ToolJet. First, let me walk you through connecting a PostgreSQL database to ToolJet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connecting the PostgreSQL database to ToolJet
&lt;/h3&gt;

&lt;p&gt;Select Global Datasources from the top-right menu bar on your ToolJet dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F36fzgt6pb7q8i1cps65j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F36fzgt6pb7q8i1cps65j.png" alt="20 description" width="800" height="638"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select PostgreSQL from the list of databases under the Global Datasources panel, and provide the required information as shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fprbrwk5kl17y8gyz901u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fprbrwk5kl17y8gyz901u.png" alt="21 description" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the image above, the host is the same as the server name on ElephantSQL (excluding the brackets). The username and database name are the same, and copy and paste the password into its field.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91e7e2werb5n2ts8lo0a.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91e7e2werb5n2ts8lo0a.jpeg" alt="22 description" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scroll down the page and click &lt;code&gt;Test Connection&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/Building%2520an%2520efficient%2520email%2520marketing%2520application%2520%2520a002a57601224c77bb03e64110b0a58e%2F23-test-connection.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/Building%2520an%2520efficient%2520email%2520marketing%2520application%2520%2520a002a57601224c77bb03e64110b0a58e%2F23-test-connection.png" alt="23-test-connection.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fduy4fw7hz4a6qy7homb8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fduy4fw7hz4a6qy7homb8.png" alt="23 description" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the connection is verified, we can start making queries to the database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faespts283b4mmrmx7sz8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faespts283b4mmrmx7sz8.png" alt="24 description" width="800" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up the database structure
&lt;/h3&gt;

&lt;p&gt;You need to create two database tables, one for the Subscribers and another for the Newsletters. &lt;/p&gt;

&lt;p&gt;Both the newsletter and subscriber table will have an &lt;code&gt;email_group&lt;/code&gt; property to enable us to identify subscribers who belong to a group and send emails to only subscribers within a group.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk15br7vqz69lt7ho5g8m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk15br7vqz69lt7ho5g8m.png" alt="25 description" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Therefore, let's create the database tables and add some dummy data. Navigate to the browser section on your ElephantSQL database and execute the code snippet below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fux6mq64sedjzetvhfrnk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fux6mq64sedjzetvhfrnk.png" alt="26 description" width="800" height="383"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;Letters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;email_group&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;published&lt;/span&gt; &lt;span class="nb"&gt;BOOLEAN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;published_date&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Letters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email_group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;published&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;published_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ToolJet v3.0 is live'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ToolJet is an open-source low-code framework that enables us to build full-stack web applications within a few minutes.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="s1"&gt;'one'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Letters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email_group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;published&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;published_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Team Community Call is live'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ToolJet is an open-source low-code framework that enables us to build full-stack web applications within a few minutes.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="s1"&gt;'two'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'01-05-2023'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Letters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email_group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;published&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;published_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Invitation to product launch'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'It is an excellent development tool helping individuals, developers, and businesses create and ship products faster.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="s1"&gt;'three'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'01-05-2023'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code snippet above creates the &lt;code&gt;Letters&lt;/code&gt; table on the database and adds three data entries: two are published, and the last one is a draft.&lt;/p&gt;

&lt;p&gt;Finally, create the Subscribers table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;Subscribers&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;organisation&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;email_group&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Subscribers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;organisation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email_group&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Jack'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'jack@gmail.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ToolJet'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="s1"&gt;'one'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Subscribers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;organisation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email_group&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Teja'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'teja@gmail.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ToolJet'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="s1"&gt;'two'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Subscribers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;organisation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email_group&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Badri'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'badri@gmail.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ToolJet'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="s1"&gt;'three'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Querying the PostgreSQL database in ToolJet
&lt;/h2&gt;

&lt;p&gt;To create the email marketing application, you need to create some database queries.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get all the subscribers.&lt;/li&gt;
&lt;li&gt;Add a new subscriber to the list.&lt;/li&gt;
&lt;li&gt;Get newsletters saved as drafts.&lt;/li&gt;
&lt;li&gt;Get published newsletters.&lt;/li&gt;
&lt;li&gt;Save a newsletter as draft.&lt;/li&gt;
&lt;li&gt;Save a published newsletter&lt;/li&gt;
&lt;li&gt;Get all the details of a published newsletter.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Getting all available subscribers
&lt;/h3&gt;

&lt;p&gt;On the &lt;code&gt;SubscriberManager&lt;/code&gt; page we need to display the list of subscribers from the database on the table as shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra8kqydqa376k7yibltk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra8kqydqa376k7yibltk.png" alt="27 description" width="800" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Therefore, create a new query on the Postgres database called &lt;code&gt;getSubscribers&lt;/code&gt; and retrieve all the data from the Subscribers table. Ensure you set the &lt;code&gt;Run this query on application load&lt;/code&gt; toggle to true.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnaj31crwszqidice6tny.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnaj31crwszqidice6tny.png" alt="28 description" width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, update the the Table data with the data returned from the query.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxbgb2cw75997m6mwh96d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxbgb2cw75997m6mwh96d.png" alt="29 description" width="800" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding a new subscriber to the list
&lt;/h3&gt;

&lt;p&gt;On the &lt;code&gt;SubscribersManager&lt;/code&gt; page, there is a &lt;code&gt;Add&lt;/code&gt; button. When you click on the button, it displays a modal that enables you to add the various details related to a subscriber.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Falaabuwv6bo7yfckn5v5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Falaabuwv6bo7yfckn5v5.gif" alt="30 description" width="600" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Therefore, you need to execute a &lt;code&gt;createSubscriber&lt;/code&gt; query when you click the Add button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5i0nqgishbax7f2b21n6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5i0nqgishbax7f2b21n6.png" alt="31 description" width="800" height="557"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Subscribers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;organisation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email_group&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'{{components.subscriberName.value}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'{{components.subscriberEmail.value}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'{{components.subscriberOrg.value}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="s1"&gt;'{{components.subscriberGroup.value}}'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code snippet above access the value of the input components on the modal. The &lt;code&gt;components&lt;/code&gt; object allows you to access every component's properties.&lt;/p&gt;

&lt;p&gt;Finally, let's run the query when a user clicks the Add button and closes the modal immediately.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi9dqdzzza3pl90jc2k4w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi9dqdzzza3pl90jc2k4w.png" alt="32 description" width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting newsletters saved as drafts
&lt;/h3&gt;

&lt;p&gt;Create a PostgreSQL query that retrieves all the newsletters saved as drafts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2eddjfwhxoegfz8f8vag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2eddjfwhxoegfz8f8vag.png" alt="33 description" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enable the Transformations below the SQL editor. It enables us to modify the data returned from the query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;imageURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.svgrepo.com/show/34217/image.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;imageURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email_group&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update the Draft tab to display the data returned from the &lt;code&gt;getDrafts&lt;/code&gt; query.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwnyukxdl9m5ppf9nocy7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwnyukxdl9m5ppf9nocy7.png" alt="34 description" width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each element on the List View displays the content using the &lt;code&gt;listItem&lt;/code&gt; property. Therefore, to access each data property, use &lt;code&gt;listItem.&amp;lt;propertyName&amp;gt;&lt;/code&gt; - &lt;code&gt;{{listItem.text}}&lt;/code&gt; and &lt;code&gt;{{listItem.group}}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcxgdmxkbawht54dnqn9a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcxgdmxkbawht54dnqn9a.png" alt="35 description" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting published newsletters
&lt;/h3&gt;

&lt;p&gt;Create a similar query to the &lt;code&gt;getDrafts&lt;/code&gt; query, which will return only newsletters whose published attribute is true.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Letters&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;published&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;TRUE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8xmtfcuh0j38r76hr9c7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8xmtfcuh0j38r76hr9c7.png" alt="36 description" width="800" height="534"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;imageURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.svgrepo.com/show/34217/image.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;imageURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;published_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email_group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code snippet above returns an image URL, text (title), date, group, and id of the published letters.&lt;/p&gt;

&lt;p&gt;Display all the published newsletters in the list view. Recall you need to use the &lt;code&gt;listItem.&amp;lt;property&amp;gt;&lt;/code&gt; method to access each attribute returned from the query.&lt;/p&gt;

&lt;h3&gt;
  
  
  Saving newsletters as draft
&lt;/h3&gt;

&lt;p&gt;Create another query that accepts the values from the &lt;code&gt;createNewsletter&lt;/code&gt; page and saves the newsletter as a draft.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Letters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email_group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;published&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;published_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'{{components.title.value}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'{{components.content.value}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'{{components.group.value}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0elgq3pc5yzufyxzzv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0elgq3pc5yzufyxzzv2.png" alt="37 description" width="800" height="558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The query is executed when a user clicks the &lt;code&gt;Save to Drafts&lt;/code&gt; button in the image below. You can redirect the user to the home page after saving the newsletter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp84qqi2yol62ccqlxgxs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp84qqi2yol62ccqlxgxs.png" alt="38 description" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Saving published newsletters
&lt;/h3&gt;

&lt;p&gt;Add another query called &lt;code&gt;savePublished&lt;/code&gt; that accepts the values from the input field and saves it as a published newsletter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Letters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email_group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;published&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;published_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'{{components.title.value}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'{{components.content.value}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'{{components.group.value}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;CURRENT_DATE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8i3zds8x1ptb6wi8jcnf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8i3zds8x1ptb6wi8jcnf.png" alt="39 description" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the query when a user clicks on the Send button. In the upcoming section, after saving the published newsletter, we'll also send it to the subscribers in that email group.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3c7ipxgwrqgkx1ze33p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3c7ipxgwrqgkx1ze33p.png" alt="40 description" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting the details of a published newsletter
&lt;/h3&gt;

&lt;p&gt;We have a page called -&lt;code&gt;viewNewsletter&lt;/code&gt; that is supposed to display the title and content of a published post when a user clicks on them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0g5z9egtn9ljnc0hovtc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0g5z9egtn9ljnc0hovtc.gif" alt="41 description" width="600" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To do this, you need to get the id of the selected newsletter and query the &lt;code&gt;Letters&lt;/code&gt; database using the id.&lt;/p&gt;

&lt;p&gt;First, add the &lt;code&gt;set Variable&lt;/code&gt; action on each row of the list view. When you click on each list item, it sets the variable's value to its index in the list view.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fdhdvsf0w8wudgwsa0k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fdhdvsf0w8wudgwsa0k.png" alt="42 description" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The variable - &lt;code&gt;selectedListviewId&lt;/code&gt; contains the selected item's index. Therefore, you can get the item's ID from the data returned from its query.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasinp4w6nl4yon6osszz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasinp4w6nl4yon6osszz.png" alt="43 description" width="800" height="452"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Letters&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="n"&gt;queries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getPublished&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;selectedListviewId&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code snippet above accesses the &lt;code&gt;variables&lt;/code&gt; object and gets the selected item's id using its index. Then, you can filter the Letters database using the id.&lt;/p&gt;

&lt;p&gt;Since we only need the title and content attribute of the newsletter. Therefore, you can update the data returned with only the required data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, run the query when a user clicks on each item of the List View.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgu1humw3ypktibhhn2h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftgu1humw3ypktibhhn2h.png" alt="44 description" width="800" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, redirect the user to the &lt;code&gt;View Newsletter&lt;/code&gt; page when they click on each item in the &lt;code&gt;List View&lt;/code&gt; to enable them to view the title and content of the newsletter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3uzbmrt8j5w7tuf0hg2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3uzbmrt8j5w7tuf0hg2.png" alt="45 description" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to communicate with ChatGPT in ToolJet
&lt;/h2&gt;

&lt;p&gt;Here, you'll learn how to communicate with ChatGPT via OpenAI in ToolJet by accepting prompts and generating email contents.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up an OpenAI account
&lt;/h3&gt;

&lt;p&gt;Log in or create an OpenAI account &lt;a href="https://openai.com/product" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Click &lt;code&gt;Personal&lt;/code&gt; on the navigation bar and select &lt;code&gt;View API keys&lt;/code&gt; from the menu bar to create a new secret key.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1x5qracbk52q7ielfj1m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1x5qracbk52q7ielfj1m.png" alt="05-openai-dashboard.png" width="800" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Generate a new API key and copy it somewhere on your computer. We'll use it in the upcoming section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Communicating with the OpenAI API in ToolJet
&lt;/h3&gt;

&lt;p&gt;Under the Global Datasources tab on your dashboard, click Plugins, and select OpenAI. Then, paste your API key and organization ID into the input fields and test the connection. &lt;/p&gt;

&lt;p&gt;You can now access the OpenAI data source from the query panel.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you don’t have an organization ID, use “Personal”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rj2w1iervux3pf3dadv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rj2w1iervux3pf3dadv.png" alt="46 description" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select OpenAI from the Query Panel and set its content to draft an email using ChatGPT.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Draft a newsletter about {{components.prompt.value}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the query when a user clicks the Ask button on the &lt;code&gt;createNewsLetter&lt;/code&gt; page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzyzz6pzgbtxxwls2y19t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzyzz6pzgbtxxwls2y19t.png" alt="47 description" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How to send emails via the Sendinblue API in ToolJet&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.sendinblue.com/" rel="noopener noreferrer"&gt;Sendinblue&lt;/a&gt; is a digital marketing tool that provides Email, SMS, Facebook, Chat, and more, via one platform to help grow businesses by building stronger customer relationships.&lt;/p&gt;

&lt;p&gt;In this section, you'll learn how to integrate and send emails via Sendinblue in ToolJet. First, you need to log in or &lt;a href="https://www.sendinblue.com/" rel="noopener noreferrer"&gt;create a SendinBlue account&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Select SMTP and API on your dashboard, generate an SMTP key, and copy it somewhere on your computer. You'll need it shortly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkz6446lsul71iz4bod6m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkz6446lsul71iz4bod6m.png" alt="28 description" width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Return to your ToolJet app, add a new SMTP data source, and fill in the required credentials. Your password is the generated SMTP key.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91mmx1nk9jo466avm3p0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91mmx1nk9jo466avm3p0.png" alt="29-smtp-datasource.png" width="800" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If successfully connected, it will display "Connection Verified". Then you can start sending emails.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqa5nup2n2i1hjp9349ou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqa5nup2n2i1hjp9349ou.png" alt="30 description" width="800" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, create the query for sending the emails. Provide your email, name, the recipient's email, subject, and title components.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx29kz0i87gw5f363qtnf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx29kz0i87gw5f363qtnf.png" alt="48 description" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the image above, the email recipient is the data returned from another query - &lt;code&gt;{{queries.querySubscriber.data}}&lt;/code&gt;. Since you need to send the newsletter to a particular group of subscribers when you select a group on the &lt;code&gt;createNewsLetter&lt;/code&gt; page. Therefore, the &lt;code&gt;querySubscriber&lt;/code&gt; query fetches the list of subscribers under a particular group.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsehq3eax8rprenteb4n8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsehq3eax8rprenteb4n8.png" alt="49 description" width="800" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above returns an array of the subscribers’ email related to the selected group. &lt;/p&gt;

&lt;p&gt;Congratulations! You’ve completed this project. Here is a working demo of the application:&lt;a href="https://app.tooljet.com/applications/toolbus-newsletter-manager-app" rel="noopener noreferrer"&gt;Toolbus newsletter manager&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also &lt;a href="https://github.com/withshubh/toolbus-newsletter-manager" rel="noopener noreferrer"&gt;download its JSON file&lt;/a&gt; and import it into a ToolJet app, but you'll need to provide your Sendinblue credentials and OpenAI API key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;So far, you've learnt how to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add a PostgreSQL database to ToolJet&lt;/li&gt;
&lt;li&gt;send emails within a ToolJet application using Sendinblue,&lt;/li&gt;
&lt;li&gt;communicate with ChatGPT in ToolJet, and&lt;/li&gt;
&lt;li&gt;build full-stack applications in a few minutes with ToolJet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/ToolJet/ToolJet" rel="noopener noreferrer"&gt;ToolJet&lt;/a&gt; is both an excellent development tool and open-source - meaning its code is readily available for everyone to modify and improve. It has a &lt;a href="https://tooljet.com/slack" rel="noopener noreferrer"&gt;large community of developers&lt;/a&gt; and talented contributors constantly maintaining and improving the software. As a user, you can be sure of getting the best performance when you use ToolJet.&lt;/p&gt;

&lt;p&gt;Are you interested in contributing to ToolJet? Feel free to check out our GitHub repo- &lt;a href="https://github.com/ToolJet/ToolJet" rel="noopener noreferrer"&gt;https://github.com/ToolJet/ToolJet&lt;/a&gt; to contribute and raise issues about ToolJet.&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>chatgpt</category>
      <category>lowcode</category>
    </item>
    <item>
      <title>Building an intelligent CRM using ChatGPT, PostgreSQL, and ToolJet</title>
      <dc:creator>Shubhendra Singh Chauhan</dc:creator>
      <pubDate>Mon, 22 May 2023 09:48:05 +0000</pubDate>
      <link>https://forem.com/tooljet/building-an-intelligent-crm-using-chatgpt-postgresql-and-tooljet-4jod</link>
      <guid>https://forem.com/tooljet/building-an-intelligent-crm-using-chatgpt-postgresql-and-tooljet-4jod</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In this tutorial, you'll learn how to build a CRM (Customer Relationship Management) application using ChatGPT, ToolJet, and PostgreSQL.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The CRM application will allow you to add new users or customers to a PostgreSQL database, view their details on a dashboard, generate email templates using ChatGPT, and send them emails via &lt;a href="https://www.sendinblue.com/" rel="noopener noreferrer"&gt;Sendinblue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We'll use ToolJet for the application interface in this tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is ToolJet?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/ToolJet/ToolJet" rel="noopener noreferrer"&gt;ToolJet&lt;/a&gt; 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.&lt;/p&gt;

&lt;p&gt;ToolJet allows you to build applications that use relational and non-relational databases, REST APIs, OpenAI technologies, and cloud storage like &lt;a href="https://cloud.google.com/storage" rel="noopener noreferrer"&gt;Google Cloud Storage&lt;/a&gt;, &lt;a href="https://aws.amazon.com/pm/serv-s3" rel="noopener noreferrer"&gt;AWS S3&lt;/a&gt;, and &lt;a href="https://min.io/" rel="noopener noreferrer"&gt;Minio&lt;/a&gt;. It is an excellent development tool helping individuals, developers, and businesses create and ship products faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before we continue, I need your help? 😔&lt;/strong&gt;&lt;br&gt;
I would be super happy if you could give us a star! And let me also know in the comments section. ❤️&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ToolJet/ToolJet" rel="noopener noreferrer"&gt;https://github.com/ToolJet/ToolJet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nfnzw4wf7oybaclylqd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8nfnzw4wf7oybaclylqd.gif" alt="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExZjlhNzRjMWJlYzgyNWZjYjcyOGMxYjJiYjQxOTQzYTU1NTg5YzAzNiZjdD1n/dfbMVqwq8GrC19xSEF/giphy.gif" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up an ElephantSQL (PostgreSQL) database
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.elephantsql.com/" rel="noopener noreferrer"&gt;ElephantSQL&lt;/a&gt; enables us to create a PostgreSQL database on the cloud instead of your local machine. Follow the steps below to create a PostgreSQL database:&lt;/p&gt;

&lt;p&gt;Create an ElephantSQL account &lt;a href="https://customer.elephantsql.com/login" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Add a new database instance. No credit card or billing information is required.&lt;/p&gt;

&lt;p&gt;Once you've created the database instance, your database information is displayed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F272zsmojx8da1ma9jvto.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F272zsmojx8da1ma9jvto.png" alt="01" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You've successfully created the database needed for this application. Next, let's build the application interface and connect the database to the application.&lt;/p&gt;
&lt;h2&gt;
  
  
  Building the application with ToolJet
&lt;/h2&gt;

&lt;p&gt;Here, you'll learn how to create a ToolJet account and build a fully functional application with ToolJet.&lt;/p&gt;

&lt;p&gt;If you are new to ToolJet, &lt;a href="https://app.tooljet.com/signup" rel="noopener noreferrer"&gt;create an account&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Create a Workspace and a new app called CRM application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyyhdhr2vw98tg2j53qj7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyyhdhr2vw98tg2j53qj7.png" alt="02-tooljet-workspace.png" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Build a user interface similar to the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzxsffw7uiwti3en9f3ug.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzxsffw7uiwti3en9f3ug.png" alt="03-app-preview.png" width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To create the UI image above, you will first add a large container on the canvas that will house all the other UI elements of the application. Next, add the three container elements at the top of the page, the Add Lead button component and the Table component.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ToolJet enables you to create applications' interfaces by dragging and dropping various UI components on the canvas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After recreating the UI, add an Action button with the text "Send Email" to the table. (We'll configure it later to enable us to email each user).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3ljnv3ovc22tvrfvhns.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3ljnv3ovc22tvrfvhns.png" alt="04-action-buttons.png" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To complete the UI, we need an interface that allows us to add a user to the database and another for editing and generating the email content for each user.&lt;/p&gt;

&lt;p&gt;To do this, we'll use the &lt;a href="https://docs.tooljet.com/docs/widgets/modal" rel="noopener noreferrer"&gt;Modal component&lt;/a&gt;. We'll display a modal when we click on the Add Lead button - for adding new data and the "Send Email" action button - for entering the email content for the user.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58ku941i3dk3ha6eseh3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58ku941i3dk3ha6eseh3.gif" alt="05-app-overview.gif" width="600" height="308"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  The “Add New Lead” Modal
&lt;/h3&gt;

&lt;p&gt;To display the Add New Lead Modal component, you need to create the modal and add an onClick event to the "Add Lead" button to show the modal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxrecm4bk2ojncpkqw3c5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxrecm4bk2ojncpkqw3c5.png" alt="06-show-modal.png" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the following components to the modal, and remember to close the modal when you click the modal button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fipm03cis8g9sqfy344j2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fipm03cis8g9sqfy344j2.png" alt="07-addnewlead-modal.png" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  The “Send Email” modal
&lt;/h3&gt;

&lt;p&gt;The Send Email modal allows us to enter the user's email, email subject, and content. You can also generate email content using the ChatGPT API. You'll learn how to do that in the upcoming sessions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxgaylavyjun43j2vvczm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxgaylavyjun43j2vvczm.gif" alt="08-sendEmail-modal.gif" width="600" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The toggle switch has an &lt;code&gt;onChange&lt;/code&gt; event that hides the ChatGPT prompt input field and button whenever you don't need it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fed9ahpchfsmbbt1lsyx9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fed9ahpchfsmbbt1lsyx9.png" alt="09-toggle-switch.png" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember to close the modal when a user clicks the &lt;code&gt;Send Email&lt;/code&gt; button.&lt;/p&gt;

&lt;p&gt;Congratulations!🎉 You've completed building the UI for this application. In the upcoming sessions, you'll learn how to connect the user interface to a PostgreSQL database, communicate with &lt;a href="https://platform.openai.com" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt;, and send emails using &lt;a href="https://www.sendinblue.com" rel="noopener noreferrer"&gt;Sendinblue&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to communicate with a PostgreSQL database in ToolJet
&lt;/h2&gt;

&lt;p&gt;ToolJet allows us to communicate with external resources or create custom functions via a panel known as &lt;a href="https://docs.tooljet.com/docs/app-builder/query-panel" rel="noopener noreferrer"&gt;Query Panel&lt;/a&gt;. In ToolJet, any function that interacts with a database, API, or cloud storage and runs a JavaScript or Python code is called a Query.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0mpk0c9lwiqt4jx45o2o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0mpk0c9lwiqt4jx45o2o.png" alt="10-query-panel.png" width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, you'll learn how to communicate with a PostgreSQL database in ToolJet. First, let me walk you through connecting a PostgreSQL database to ToolJet.&lt;/p&gt;
&lt;h3&gt;
  
  
  Connecting a PostgreSQL database to ToolJet
&lt;/h3&gt;

&lt;p&gt;Select PostgreSQL from the list of databases under the Global Datasources panel, and provide the required information as shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F664hgiq624ad21dkkunf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F664hgiq624ad21dkkunf.png" alt="11-add-postgres.png" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the image above, the host is the same as the server name on ElephantSQL (excluding the brackets). The username and database name are the same, and copy and paste the password into its field.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgvrrd2g3dc0wakzrpkp0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgvrrd2g3dc0wakzrpkp0.png" alt="12-connect-elephantSQL.png" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scroll down the page and click &lt;code&gt;Test Connection&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftz0p08ohre5gl02ovdq6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftz0p08ohre5gl02ovdq6.png" alt="13-test-connection.png" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the connection is verified, we can start making queries to the database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxdklu8d2slcwc5efs6sy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxdklu8d2slcwc5efs6sy.png" alt="14-connection-verified.png" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Querying a PostgreSQL database in ToolJet
&lt;/h3&gt;

&lt;p&gt;Here, you'll learn how to query data from the database and display them accordingly within the application.&lt;/p&gt;

&lt;p&gt;Before we begin, let's add some data to the database. Click PostgreSQL on the Query Panel, select SQL mode, and run the code snippet below to create a new table containing the data below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;Users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Phone&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Organisation&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Designation&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;organisation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;designation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Teja'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'teja@gmail.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'+555-34569'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ToolJet'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Developer Advocate'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Customer'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;organisation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;designation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Badri'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'badri@gmail.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'+555-59659'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ToolJet'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Engineering Manager'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Prospect'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;organisation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;designation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Jack'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'jack@gmail.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'+555-44449'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ToolJet'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Software Engineer'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Lead'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;organisation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;designation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Nora'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'nora@gmail.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'+555-46249'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ToolJet'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Product Manager'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Customer'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;organisation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;designation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Emily'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'emily@gmail.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'+555-47893'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ToolJet'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Product Designer'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Prospect'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;organisation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;designation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Dave'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'dave@gmail.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'+555-49313'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ToolJet'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Data analyst'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Lead'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl4dh6d064s6cl9dfl7ej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl4dh6d064s6cl9dfl7ej.png" alt="15-add-data.png" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can view the data on ElephantSQL once it has been uploaded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2t17ppq1t2tcjswba0gj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2t17ppq1t2tcjswba0gj.png" alt="16-view-data.png" width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, rename the query to &lt;code&gt;getTableData&lt;/code&gt;, update the SQL editor to display all the table contents, and save the query.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdx1k68qvppa4m038jhwk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdx1k68qvppa4m038jhwk.png" alt="17-rename-query.png" width="800" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update the Table component to display the data retrieved from the &lt;code&gt;getTableData&lt;/code&gt; query.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftny1jrfuf24zncb2bpzp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftny1jrfuf24zncb2bpzp.png" alt="18-displayTable-data.png" width="800" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since we've displayed the contents on the table. Next, let's show the number of Customers, Leads, and Prospects available on the database.&lt;/p&gt;

&lt;p&gt;Create three new queries based on the PostgreSQL database called &lt;code&gt;getLeadsCount&lt;/code&gt;, &lt;code&gt;getProspectsCount&lt;/code&gt;, and &lt;code&gt;getCustomersCount&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Update the SQL editor for each query to retrieve the number of data under each category as done below, and save them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;Users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Lead'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="cm"&gt;/*-- change 'Lead' for leads, 'Prospect' for prospects, 'Customer' for customers. ---*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4s3eoizatiilzi1wopx5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4s3eoizatiilzi1wopx5.png" alt="19-display-counts.png" width="800" height="127"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Display the number of data returned from each query by replacing the text content within the container as done below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fug6uu7akdon95kas4auu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fug6uu7akdon95kas4auu.png" alt="20-getData-counts.png" width="800" height="156"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{queries.getProspectsCount.data[0].count}}

//(Use {{queries.getLeadsCount.data[0].count}} for leads and {{queries.getCustomersCount.data[0].count}} for customers)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, switch on the "Run this query on application load?" toggle for the &lt;code&gt;getTableData&lt;/code&gt; and the other three queries.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdkxohslstg1dprl213g7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdkxohslstg1dprl213g7.png" alt="21-run-app.png" width="800" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You've learnt how to query and display the data received within the application. Next, I will walk you through adding new data to the database via the application interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding new users to the database
&lt;/h3&gt;

&lt;p&gt;Here, you'll learn how to accept that data from the modal and add the user's data to the database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdpqc7ib88l68xc20n5b5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdpqc7ib88l68xc20n5b5.png" alt="22a-addNewUser.png" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a new query related to the PostgreSQL data source that accepts the values from the modal and sends an SQL query to add the data to the database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fllhizit4gvm8gxw7uv52.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fllhizit4gvm8gxw7uv52.png" alt="22-add-user.png" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ensure that the code snippet below matches the components' names from the modal. Copy the code snippet below into the SQL editor panel and save the query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;organisation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;designation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'{{components.name.value}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'{{components.email.value}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'{{components.phone.value}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'{{components.organisation.value}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'{{components.designation.value}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'{{components.status.value}}'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, add an &lt;code&gt;onClick&lt;/code&gt; event to the &lt;code&gt;Add Lead&lt;/code&gt; button to run the query on button click.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawdjo4kiivm8ro2z38yo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawdjo4kiivm8ro2z38yo.png" alt="23-addNewUser.png" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to communicate with ChatGPT in ToolJet
&lt;/h2&gt;

&lt;p&gt;Here, you'll learn how to communicate with ChatGPT via OpenAI in ToolJet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up an OpenAI account
&lt;/h3&gt;

&lt;p&gt;Log in or create an OpenAI account &lt;a href="https://openai.com/product" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Click &lt;code&gt;Personal&lt;/code&gt; on the navigation bar and select &lt;code&gt;View API keys&lt;/code&gt; from the menu bar to create a new secret key.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ggxnieexrli2bpxp2in.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ggxnieexrli2bpxp2in.png" alt="05-openai-dashboard.png" width="800" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Generate a new API key and copy it somewhere on your computer. We'll use it in the upcoming section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Communicating with the OpenAI API in ToolJet
&lt;/h3&gt;

&lt;p&gt;Under the Global Datasources tab on your dashboard, click Plugins, and select OpenAI. Then, paste your API key and organization ID into the input fields and test the connection. &lt;/p&gt;

&lt;p&gt;You can now access the OpenAI data source from the query panel.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you don’t have an organization ID, use “Personal”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0rqvh327achnh3mwhii.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0rqvh327achnh3mwhii.png" alt="24-openai-connection.png" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select OpenAI from the Query Panel and set its content to draft an email using ChatGPT.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Draft an email to {{components.recipient.value}} about {{components.chatgptprompt.value}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the query when a user clicks the Ask button on the modal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcllzbj9iv7ryzm4o0w6p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcllzbj9iv7ryzm4o0w6p.png" alt="26-run-chatgpt.png" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, to display a selected user's email automatically on the modal, set the default value of the recipient's email input to &lt;code&gt;{{components.table1.selectedRow.email}}&lt;/code&gt;. This automatically sets its value to the email of the selected user.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkq813x6psxx3fe35jwau.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkq813x6psxx3fe35jwau.png" alt="27-autochange-email.png" width="800" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to send emails via the Sendinblue API in ToolJet
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.sendinblue.com/" rel="noopener noreferrer"&gt;Sendinblue&lt;/a&gt; is a digital marketing tool that provides Email, SMS, Facebook, Chat, and more, via one platform to help grow businesses by building stronger customer relationships.&lt;/p&gt;

&lt;p&gt;In this section, you'll learn how to integrate and send emails via Sendinblue in ToolJet. First, you need to log in or &lt;a href="https://www.sendinblue.com/" rel="noopener noreferrer"&gt;create a SendinBlue account&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Select SMTP and API on your dashboard, generate an SMTP key, and copy it somewhere on your computer. You'll need it shortly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqzhwyacxvnj0skxjhdv5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqzhwyacxvnj0skxjhdv5.png" alt="28-generate-smtp.png" width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Return to your ToolJet app, add a new SMTP data source, and fill in the required credentials. Your password is the generated SMTP key.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fukhdscpvuvf4hxmgve31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fukhdscpvuvf4hxmgve31.png" alt="29-smtp-datasource.png" width="800" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If successfully connected, it will display "Connection Verified". Then you can start sending emails.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F219asl8q2w4v36w7x3xj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F219asl8q2w4v36w7x3xj.png" alt="30-connect-verified.png" width="800" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, create the query for sending the emails. Provide your email, name, the recipient's email, subject, and title components.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fav3n0c9ehjkizprq18f5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fav3n0c9ehjkizprq18f5.png" alt="31-smtp-config.png" width="800" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, save the query and run it when the Send Email button on the modal is clicked.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzza3wsg0hrv641hvwlv6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzza3wsg0hrv641hvwlv6.png" alt="32-app-reveal.png" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a working demo of the application: &lt;a href="https://tooljet-stny.onrender.com/applications/7a8867e3-3cea-49e3-89e7-8da39038b875" rel="noopener noreferrer"&gt;https://tooljet-stny.onrender.com/applications/7a8867e3-3cea-49e3-89e7-8da39038b875&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also &lt;a href="https://tooljet.com/" rel="noopener noreferrer"&gt;download its JSON file&lt;/a&gt; and import it into a ToolJet app, but you'll need to provide your Sendinblue credentials and OpenAI API key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;So far, you've learnt how to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add a PostgreSQL database to ToolJet&lt;/li&gt;
&lt;li&gt;send emails within a ToolJet application using Sendinblue,&lt;/li&gt;
&lt;li&gt;communicate with ChatGPT via OpenAI in ToolJet, and&lt;/li&gt;
&lt;li&gt;Build full-stack applications in a few minutes with ToolJet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/ToolJet/ToolJet" rel="noopener noreferrer"&gt;ToolJet&lt;/a&gt; is both an excellent development tool and open-source - meaning its code is readily available for everyone to modify and improve. It has a &lt;a href="https://tooljet.slack.com/ssb/redirect" rel="noopener noreferrer"&gt;large community of developers&lt;/a&gt; and talented contributors constantly maintaining and improving the software. As a user, you can be sure of getting the best performance when you use ToolJet.&lt;/p&gt;

&lt;p&gt;Are you interested in contributing to ToolJet? Feel free to check out our GitHub repo- &lt;a href="https://github.com/ToolJet/ToolJet" rel="noopener noreferrer"&gt;https://github.com/ToolJet/ToolJet&lt;/a&gt; to contribute and raise issues about ToolJet.&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>chatgpt</category>
      <category>lowcode</category>
    </item>
    <item>
      <title>Build your own CMS using low-code</title>
      <dc:creator>Shubhendra Singh Chauhan</dc:creator>
      <pubDate>Tue, 28 Mar 2023 06:21:33 +0000</pubDate>
      <link>https://forem.com/tooljet/build-your-own-cms-using-low-code-2lgo</link>
      <guid>https://forem.com/tooljet/build-your-own-cms-using-low-code-2lgo</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In this tutorial, We will build CMS(Content Management System) using the ToolJet which is a lowcode application development platform. The CMS can be used to perform CRUD operations to the MongoDB which is used as the database for the NextJS application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Table of Contents
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Overview&lt;/li&gt;
&lt;li&gt;Prerequisites&lt;/li&gt;
&lt;li&gt;Setting up the database&lt;/li&gt;
&lt;li&gt;Connecting MongoDB to ToolJet&lt;/li&gt;
&lt;li&gt;Building the UI, Queries and connecting them&lt;/li&gt;
&lt;li&gt;Connecting to NextJS app&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;content management system (CMS)&lt;/strong&gt; is an application used for managing content creation and modification, usually articles and blog posts containing images and videos. WordPress CMS is one of the popular CMS. CMSs make it easy to perform CRUD operations (create, read, update, and delete) without coding knowledge.&lt;br&gt;
&lt;a href="https://tooljet.com" rel="noopener noreferrer"&gt;ToolJet&lt;/a&gt; is a free and &lt;a href="https://github.com/tooljet/tooljet" rel="noopener noreferrer"&gt;open-source&lt;/a&gt; low-code app development platform that allows you to build applications quickly and has more than 30+ datasources including &lt;a href="https://www.mongodb.com/" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt; that will let you seamlessly perform operations on your database. You can create a free account on ToolJet Cloud or run it on your &lt;a href="https://docs.tooljet.com/docs/setup/" rel="noopener noreferrer"&gt;local machine&lt;/a&gt;.&lt;br&gt;
Many developers use databases like MongoDB and frameworks like NextJS for their full-stack web applications. Sometimes performing CRUD operations can be time taking for developers and can be hectic for someone who is not familiar with running database queries. In this tutorial, we will build an app using ToolJet that will solve these problems. The CMS app will be connected to the MongoDB database to perform CRUD operation, and the changes will be reflected on the &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;NextJS&lt;/a&gt; application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F02%2Fpika-1677498610481-1x.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F02%2Fpika-1677498610481-1x.jpeg" alt="appui" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want to use the app without going through the complete tutorial?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Import the exported application JSON file to your ToolJet account. Here's the &lt;a href="https://blog.tooljet.com/content/files/2023/02/cms_mongo-export-1677491297947.json" rel="noopener noreferrer"&gt;file&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Once imported the application, you'll need to connect the MongoDB datasource using host details or &lt;strong&gt;connection string&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;MongoDB database&lt;/strong&gt;: You can set up the MongoDB database locally or use &lt;a href="https://www.mongodb.com/atlas/database" rel="noopener noreferrer"&gt;Atlas&lt;/a&gt;. For this tutorial, we are going to use Atlas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ToolJet&lt;/strong&gt; (&lt;a href="https://github.com/ToolJet/ToolJet):" rel="noopener noreferrer"&gt;https://github.com/ToolJet/ToolJet):&lt;/a&gt; A free and open-source low-code platform that allows you to build applications quickly. Sign up &lt;a href="https://tooljet.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;NextJS app&lt;/a&gt;&lt;/strong&gt;: We will learn how to build one sample app using the command line later in this tutorial.&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  Setting up the database
&lt;/h2&gt;

&lt;p&gt;Once you have created an account on MongoDB Atlas, you'll be asked to enter the &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt; for your database (not the same as what you use to log into the MongoDB cloud). Once done, you'll be redirected to your project's database deployment, where you can create/manage Clusters. You can create a new Cluster and choose a configuration according to your preference.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-02-at-9.40.15-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-02-at-9.40.15-AM.png" alt="mongo1" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see in the screenshot above, we have  &lt;code&gt;Cluster0&lt;/code&gt; deployed. Go to the &lt;code&gt;browse collections&lt;/code&gt; and create a new database &lt;code&gt;cms&lt;/code&gt; with three collections &lt;code&gt;posts&lt;/code&gt;, &lt;code&gt;authors&lt;/code&gt;, and &lt;code&gt;tags&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;posts&lt;/code&gt;- this collection will store all the blog posts information&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;authors&lt;/code&gt;- this collection will store information on all the authors&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tags&lt;/code&gt; - this collection will store the tags&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's insert at least one sample document in each collection. For posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;_id&lt;/code&gt;: the object id will be generated by MongoDB automatically.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;title&lt;/code&gt;: enter the title of the blog posts.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;subtitle&lt;/code&gt;: enter the subtitle&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;content&lt;/code&gt;: enter the content/body of blog posts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cover&lt;/code&gt;: enter the URL of the cover image&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;author_name&lt;/code&gt;: enter the name of the author&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tag_name&lt;/code&gt;: enter the tag name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;published_on&lt;/code&gt;: enter the date in DD/MM/YYYY format
The data type of all the records should be &lt;strong&gt;string&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-02-at-10.08.21-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-02-at-10.08.21-AM.png" alt="object" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similarly, we will insert documents in authors and tags. For authors&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;_id&lt;/code&gt;: the object id will be generated by MongoDB automatically.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;author_name&lt;/code&gt;: name of the author&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;author_email&lt;/code&gt;: email of the author&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;author_image&lt;/code&gt;: URL of author's headshot image&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-02-at-10.08.54-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-02-at-10.08.54-AM.png" alt="authors" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;tags&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;_id&lt;/code&gt;: the object id will be generated by MongoDB automatically.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tag_name&lt;/code&gt;: name of the tag&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you have inserted the sample documents in all three collections, we are good to go. Our database is ready.&lt;/p&gt;

&lt;p&gt;Now, let's go to ToolJet and connect the database.&lt;/p&gt;


&lt;h2&gt;
  
  
  Connecting MongoDB to ToolJet
&lt;/h2&gt;

&lt;p&gt;Let's go to the &lt;strong&gt;ToolJet dashboard&lt;/strong&gt; and create a &lt;strong&gt;new app&lt;/strong&gt;. Once you click the &lt;strong&gt;New App button&lt;/strong&gt;, an untitled app will open in the app builder. You can rename the app from the toolbar. On the left sidebar, you'll find the third option for adding or editing datasources.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-06-at-6.53.03-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-06-at-6.53.03-PM.png" alt="newapp" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the &lt;strong&gt;+ add datasource&lt;/strong&gt; and a modal will pop up with a list of all the available datasources. Select &lt;strong&gt;MongoDB&lt;/strong&gt; from the list and enter the credentials for connecting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-06-at-6.59.59-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-06-at-6.59.59-PM.png" alt="datasource" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this tutorial, we are using MongoDB Atlas to connect to MongoDB datasource using the &lt;strong&gt;connection string&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-06-at-7.03.44-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-06-at-7.03.44-PM.png" alt="creds" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can find your connection string by going to the MongoDB Atlas dashboard. Go to &lt;code&gt;Database Deployments&lt;/code&gt; on the Atlas and click on the &lt;strong&gt;Connect&lt;/strong&gt; button next to the cluster name ( &lt;strong&gt;Cluster0&lt;/strong&gt; in our case). A connection dialog will pop up to choose the method by which you want to connect, click on the second option - &lt;strong&gt;Connect your application&lt;/strong&gt;. Once you click on the second option, you'll get the connection string - click on the copy button next to it to copy the string.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-06-at-7.05.39-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-06-at-7.05.39-PM.png" alt="mongodash" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The string that you'll copy will be like this &lt;code&gt;mongodb+srv://testusername:&amp;lt;password&amp;gt;@cluster0.nc8nial.mongodb.net/?retryWrites=true&amp;amp;w=majority&lt;/code&gt; where &lt;code&gt;testusername&lt;/code&gt; is the database username that we created before, we will need to replace &lt;code&gt;&amp;lt;password&amp;gt;&lt;/code&gt; with the password that we created for this database and then remove everything after &lt;code&gt;.net/&lt;/code&gt; and add your database name - in our case, the name of the database is &lt;code&gt;cms&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, the actual connection string will be: &lt;code&gt;mongodb+srv://testusername:fakepassword@cluster0.nc8nial.mongodb.net/cms&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Copy-paste the connection string on the ToolJet and click on the test connection button to test the connection before saving the datasource once the connection is &lt;strong&gt;successful&lt;/strong&gt; then save the datasource.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-06-at-7.10.50-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-06-at-7.10.50-PM.png" alt="success" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, that we have successfully connected the MongoDB database, we can build the user interface of the CMS app.&lt;/p&gt;


&lt;h2&gt;
  
  
  Build the UI of the CMS app
&lt;/h2&gt;

&lt;p&gt;Let's start building the UI of the CMS application using ToolJet, which is a low-code application development platform.&lt;/p&gt;

&lt;p&gt;The CMS application is a &lt;a href="https://docs.tooljet.com/docs/tutorial/pages" rel="noopener noreferrer"&gt;multi-page application&lt;/a&gt; that will have the following 5 pages:&lt;/p&gt;
&lt;h3&gt;
  
  
  All Posts
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.05.35-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.05.35-PM.png" alt="allpostsimage" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  New Post
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.06.08-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.06.08-PM.png" alt="newpostimage" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Edit Post
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.06.25-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.06.25-PM.png" alt="editpost" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  View Post
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.07.04-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.07.04-PM.png" alt="viewpost" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Authors and Tags
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.07.54-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.07.54-PM.png" alt="allpostsimage" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the previous section, we connected the MongoDB datasource to a new application. Now, all we need to do is build the UI and then create queries and connect them with the UI.&lt;/p&gt;

&lt;p&gt;The very first thing we are going to do is create Pages in our application. We can find the Pages option on the left sidebar from where we can add the pages to the application. Let's add the following pages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;all_posts&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;new_post&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;edit_post&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;view_post&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;authors_tags&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-16-at-5.37.41-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-16-at-5.37.41-PM.png" alt="pages" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Before we begin with UI, it is recommended to learn about ToolJet's app builder: &lt;a href="https://docs.tooljet.com/docs/app-builder/overview" rel="noopener noreferrer"&gt;https://docs.tooljet.com/docs/app-builder/overview&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  All Posts: UI
&lt;/h3&gt;

&lt;p&gt;The All Posts page will show the list of all the blog posts. This is going to be the home page of the application, and from this page, we can navigate to other pages.&lt;/p&gt;

&lt;p&gt;This page will use the listview component to show a list of blogs and buttons to navigate other pages. Let's build the UI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's drag a &lt;strong&gt;container&lt;/strong&gt; on the &lt;strong&gt;canvas&lt;/strong&gt; and increase its height to reach the bottom and its width to both sides. You can click on the handle of the container to edit its properties.&lt;/li&gt;
&lt;li&gt;Drag a text component and set its value to &lt;code&gt;&amp;lt;h1&amp;gt;All Posts&amp;lt;/h1&amp;gt;&lt;/code&gt;. Yes, we can use HTML tags inside the text component to format text value.&lt;/li&gt;
&lt;li&gt;Drag a divider below the text component.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.40.57-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.40.57-PM.png" alt="all_post_ui" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now drag two &lt;strong&gt;button&lt;/strong&gt; components above the right side of the divider and style the buttons.&lt;/li&gt;
&lt;li&gt;For the first button, we will set the button text to &lt;strong&gt;New Post&lt;/strong&gt; and edit its &lt;strong&gt;Styles&lt;/strong&gt;. Set the button color to &lt;code&gt;#14171a&lt;/code&gt; , text color to &lt;code&gt;white/#ffffff&lt;/code&gt;, loader color to &lt;code&gt;white&lt;/code&gt;, border-radius to &lt;code&gt;2&lt;/code&gt; , border color to &lt;code&gt;#14171a&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add an &lt;strong&gt;Event Handler&lt;/strong&gt; to the &lt;strong&gt;New Post&lt;/strong&gt; button, choose &lt;strong&gt;switch page&lt;/strong&gt; action, and then select the &lt;code&gt;new_post&lt;/code&gt; from the dropdown. Now, whenever the button is clicked &lt;code&gt;New Post&lt;/code&gt; page of the application will be loaded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.47.56-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.47.56-PM.png" alt="allpostui" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For the second button, we will set the button text to &lt;strong&gt;Authors and Tags&lt;/strong&gt; and edit its &lt;strong&gt;Styles&lt;/strong&gt;. Set the button color to &lt;code&gt;white/#ffffff&lt;/code&gt; , text color to &lt;code&gt;#14171a&lt;/code&gt;, loader color to &lt;code&gt;#14171a&lt;/code&gt;, border-radius to &lt;code&gt;2&lt;/code&gt; , border color to &lt;code&gt;#14171a&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add an &lt;strong&gt;Event Handler&lt;/strong&gt; to the &lt;strong&gt;Authors &amp;amp; Tags&lt;/strong&gt; button, choose &lt;strong&gt;switch page&lt;/strong&gt; action, and select the &lt;code&gt;authors_tags&lt;/code&gt; from the dropdown. Now, whenever the button is clicked &lt;code&gt;Authors &amp;amp; Tags&lt;/code&gt; page of the application will be loaded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.55.03-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-4.55.03-PM.png" alt="authortagss" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now drag a &lt;strong&gt;listview&lt;/strong&gt; component below the &lt;strong&gt;divider&lt;/strong&gt;. Go to its &lt;strong&gt;Styles&lt;/strong&gt; and set the border color to white.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-5.09.45-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-5.09.45-PM.png" alt="listview1" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's add &lt;strong&gt;components&lt;/strong&gt; inside the listview. Remove the &lt;strong&gt;image&lt;/strong&gt; component, and add &lt;strong&gt;three text components&lt;/strong&gt; and &lt;strong&gt;two buttons&lt;/strong&gt; as shown in the image below.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-6.17.46-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-6.17.46-PM.png" alt="listview2" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Currently, the listview looks very rough since we haven't styled the nested components (text and buttons) yet. To make it look better, we can add some styling to the components and some placeholder text until we create the query for the data to be loaded into the listview.&lt;/li&gt;
&lt;li&gt;Let's edit the properties and styles of the nested text components and buttons:

&lt;ul&gt;
&lt;li&gt;text1: Text = &lt;code&gt;Title of the blog&lt;/code&gt; , Font weight = &lt;code&gt;Bold&lt;/code&gt; , Font size = &lt;code&gt;16&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;text2: Text = &lt;code&gt;By Author - 06/02/2023&lt;/code&gt; , Font weight = &lt;code&gt;Lighter&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;text3: Text = &lt;code&gt;Tag&lt;/code&gt; , Font weight = &lt;code&gt;Lighter&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;button1: Button text = 👁️ , Background color = &lt;code&gt;white&lt;/code&gt; , Border radius = &lt;code&gt;2&lt;/code&gt; , Border color = &lt;code&gt;#e2e4e4&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;button2: &lt;code&gt;Button&lt;/code&gt; text = ✏️ , Background color = &lt;code&gt;white&lt;/code&gt; , Border radius = &lt;code&gt;2&lt;/code&gt; , Border color = &lt;code&gt;#e2e4e4&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-6.44.07-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-6.44.07-PM.png" alt="listview3" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For the view/👁️ and edit/✏️ buttons inside listview, we need to add event handlers. On both buttons, we need to add an event handler for &lt;code&gt;set variable&lt;/code&gt; event that creates a variable &lt;code&gt;selectedListViewIndex&lt;/code&gt; and the variable value will be &lt;code&gt;{{listItem._id}}&lt;/code&gt; - this value will be there once we create the query. Another event handler that we need to add is to switch the page, for the edit button link &lt;code&gt;edit_post&lt;/code&gt; page and for the view button link &lt;code&gt;view_post&lt;/code&gt; page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-6.49.32-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-16-at-6.49.32-PM.png" alt="listview4" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The UI of the All Posts page is almost finished, now let's go ahead and build the queries and connect to the UI.&lt;/p&gt;
&lt;h3&gt;
  
  
  All Posts: Queries
&lt;/h3&gt;

&lt;p&gt;Let's build the required query for loading the data on All Posts page. Since we are only loading the list of all the blogs from the database on the listview, we need to build a single query:&lt;/p&gt;
&lt;h4&gt;
  
  
  posts
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Go to the query panel at the bottom of the app builder, create a new MongoDB query, and name it as &lt;code&gt;posts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select the &lt;strong&gt;Find Many&lt;/strong&gt; &lt;strong&gt;Operation&lt;/strong&gt; from the dropdown options and then enter the &lt;strong&gt;Collection&lt;/strong&gt; name as &lt;code&gt;posts&lt;/code&gt; which is the name of the collection in our &lt;code&gt;cms&lt;/code&gt; db that we created in MongoDB Atlas&lt;/li&gt;
&lt;li&gt;From the &lt;strong&gt;Advanced&lt;/strong&gt; section, toggle on the &lt;code&gt;Run query on application load?&lt;/code&gt; option, and then &lt;strong&gt;save&lt;/strong&gt; the query. This will execute the query every time the app is loaded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run&lt;/strong&gt; the query to trigger it, and we can check the data returned by the query from the inspector panel on the left sidebar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-10.04.59-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-10.04.59-AM.png" alt="postsquery" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  authors
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Create a new MongoDB query, and name it as authors&lt;/li&gt;
&lt;li&gt;Select the &lt;code&gt;Find Many&lt;/code&gt; &lt;strong&gt;Operation&lt;/strong&gt; from the dropdown options and then enter the Collection name as &lt;code&gt;authors&lt;/code&gt; which is the name of the &lt;strong&gt;collection&lt;/strong&gt; in our cms db that we created in MongoDB Atlas&lt;/li&gt;
&lt;li&gt;From the &lt;strong&gt;Advanced&lt;/strong&gt; section, toggle on the &lt;code&gt;Run query on application load?&lt;/code&gt; option, and then &lt;strong&gt;save&lt;/strong&gt; the query. This will execute the query every time the app is loaded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run&lt;/strong&gt; the query to trigger it and we can check the data returned by the query from the inspector panel on the left sidebar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-10.34.03-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-10.34.03-AM.png" alt="authorsquery" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  tags
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Create a new MongoDB query, and name it as &lt;code&gt;tags&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select the &lt;code&gt;Find Many&lt;/code&gt; &lt;strong&gt;Operation&lt;/strong&gt; from the &lt;strong&gt;dropdown&lt;/strong&gt; options and then enter the Collection name as &lt;code&gt;tags&lt;/code&gt; which is the name of the &lt;strong&gt;collection&lt;/strong&gt; in our cms db that we created in MongoDB Atlas&lt;/li&gt;
&lt;li&gt;From the &lt;strong&gt;Advanced&lt;/strong&gt; section, toggle on the &lt;code&gt;Run query on application load?&lt;/code&gt; option, and then save the query. This will execute the query every time the app is loaded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run&lt;/strong&gt; the query to trigger it and we can check the data returned by the query from the inspector panel on the left sidebar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-10.34.20-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-10.34.20-AM.png" alt="tags query" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  All Posts: Connecting queries data to UI
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Now, that we have the &lt;code&gt;posts&lt;/code&gt;, &lt;code&gt;authors&lt;/code&gt;, and &lt;code&gt;tags&lt;/code&gt; data from the database, we can populate the listview component. Edit the properties of the ListView component and set the &lt;strong&gt;List data&lt;/strong&gt; value to &lt;code&gt;{{queries.posts.data}}&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-10.09.39-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-10.09.39-AM.png" alt="connectingui" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The rows will be added to the listview but the actual data won't show up because the components inside the listview currently hold the placeholder values. Let's remove the placeholder values from the components inside the ListView. Go to the text component whose value is &lt;code&gt;Title of the blog&lt;/code&gt; and set its value to &lt;code&gt;{{listItem.title}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-10.13.19-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-10.13.19-AM.png" alt="uititle" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set the value of the second text component to &lt;code&gt;By {{listItem.author_name}} -  {{listItem.published_on}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Set the value of the third text component to &lt;code&gt;{{listItem.tag_name}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-10.39.28-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-10.39.28-AM.png" alt="uiauthor" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are finally done with the &lt;strong&gt;All Posts&lt;/strong&gt; page, all we need to do now is build the UI of the remaining 4 pages and then connect the queries.&lt;/p&gt;


&lt;h3&gt;
  
  
  New post: UI
&lt;/h3&gt;

&lt;p&gt;The New Post page will be used to create a new blog post and insert it into the collection &lt;code&gt;posts&lt;/code&gt;. Let's click on the &lt;strong&gt;New Post&lt;/strong&gt; button on the top of the &lt;strong&gt;All Post&lt;/strong&gt; page and switch to the &lt;code&gt;new_post&lt;/code&gt; page as we have already added the event handler to the button.&lt;/p&gt;

&lt;p&gt;This page will use the container component as the body and we will nest components like text, text-input, dropdown, etc. to create a form-like structure for getting the input from the users. Let's build the UI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We are going to build a UI similar to the UI that we build for the &lt;strong&gt;All Posts&lt;/strong&gt; page. First, we will drag a container component onto the canvas and then we will use the text component for the Title of the page i.e &lt;code&gt;New Post&lt;/code&gt; with a divider component below it.&lt;/li&gt;
&lt;li&gt;On the right side of the divider, we can simply copy and paste the &lt;code&gt;Authors &amp;amp; Tags&lt;/code&gt; button from the All posts page and paste it into the New Post page. Change the button text to &lt;strong&gt;&amp;lt; Back&lt;/strong&gt; and add the &lt;strong&gt;event handler&lt;/strong&gt; to &lt;strong&gt;switch the page&lt;/strong&gt; to &lt;code&gt;all_posts&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-17-at-2.56.52-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-17-at-2.56.52-PM.png" alt="dividerui" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now we are going to drag components and build a form-like structure below the divider component.

&lt;ul&gt;
&lt;li&gt;We are going to drag a text component, set its value to Title, set Font weight to Bold, and Font Size to 16&lt;/li&gt;
&lt;li&gt;We will copy-paste(using &lt;a href="https://docs.tooljet.com/docs/tutorial/keyboard-shortcuts" rel="noopener noreferrer"&gt;keyboard shortcuts&lt;/a&gt;) the Title text component 5 more times and then change their text to Subtitle, Content, Cover Image, Author, and Tag, respectively.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Now, we will place the following components next to the headings:

&lt;ul&gt;
&lt;li&gt;Title: text input component and set placeholder to Title&lt;/li&gt;
&lt;li&gt;Subtitle: text input component and set placeholder to Subtitle&lt;/li&gt;
&lt;li&gt;Content: text area component and set placeholder to Content&lt;/li&gt;
&lt;li&gt;Cover Image: text input component and set placeholder to Cover Image&lt;/li&gt;
&lt;li&gt;Author: dropdown component and set placeholder to Author&lt;/li&gt;
&lt;li&gt;Tag: dropdown component and set placeholder to Tag&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Set the value of the border radius of all the input components to &lt;code&gt;{{2}}&lt;/code&gt; to make them look better&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-2.59.11-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-2.59.11-PM.png" alt="formui" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our form is almost complete, now at the bottom of the page we will add a button. We will copy-paste the button from the &lt;strong&gt;All Posts&lt;/strong&gt; page and change the button text to &lt;strong&gt;Submit&lt;/strong&gt;. Remove the existing event handlers, and add an event handler to switch the page to &lt;code&gt;all_posts&lt;/code&gt; . We will add another event handler once we create the query for submitting the form.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-3.10.49-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-3.10.49-PM.png" alt="formui2" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The UI for creating a new blog post is ready, now let's create the query for inserting the form values into the database.&lt;/p&gt;
&lt;h3&gt;
  
  
  New post: Queries
&lt;/h3&gt;
&lt;h4&gt;
  
  
  add_post
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Create a new MongoDB query, and name it as add_post&lt;/li&gt;
&lt;li&gt;Select the &lt;code&gt;Insert One&lt;/code&gt; &lt;strong&gt;Operation&lt;/strong&gt; from the dropdown options and then enter the &lt;strong&gt;Collection&lt;/strong&gt; name as &lt;code&gt;posts&lt;/code&gt; which is the name of the collection in our cms db that we created in MongoDB Atlas&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Document&lt;/strong&gt; field, enter the following:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.textinput1.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subtitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.textinput2.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.richtexteditor1.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.textinput3.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;author_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.dropdown1.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tag_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.dropdown2.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;published_on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{moment().format(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;DD&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;MM&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;YYYY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;)}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;In the code snippet above, we are &lt;strong&gt;dynamically&lt;/strong&gt; getting values from the input components.&lt;/li&gt;
&lt;li&gt;Go to the bottom of the query manager and add the event handler to &lt;strong&gt;run the query&lt;/strong&gt; on the &lt;strong&gt;Query Success&lt;/strong&gt; event and select the posts query. Doing this will trigger the posts query every time this add_post query is successful or simple words whenever the user submits the blog then the list of the blogs will be refreshed on the front-end. Finally, &lt;strong&gt;Save&lt;/strong&gt; the query.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-4.38.48-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-4.38.48-PM.png" alt="querymanager" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  New post: Connecting queries data to UI
&lt;/h4&gt;

&lt;p&gt;On this page, all we need to do is connect the query that we created in the previous step to the submit button so that whenever the button gets clicked, the query for inserting the post is triggered and then the page switches to the home page i.e. All Posts page.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the handle of the &lt;strong&gt;Submit&lt;/strong&gt; button, and go to the &lt;strong&gt;Events&lt;/strong&gt; section under its properties.&lt;/li&gt;
&lt;li&gt;While building the UI we already added an &lt;strong&gt;event handler&lt;/strong&gt; for &lt;strong&gt;switching&lt;/strong&gt; the page to &lt;code&gt;all_posts&lt;/code&gt;, now we need to add another event handler to &lt;strong&gt;Run the query&lt;/strong&gt; on the &lt;strong&gt;On Click&lt;/strong&gt; event -&amp;gt; Select the &lt;code&gt;add_post&lt;/code&gt; query. Move the Run query event handler above the Switch Page event handler to ensure the query runs first and then the page switches to the home page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-17-at-5.02.37-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-17-at-5.02.37-PM.png" alt="onclickui" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Edit post: UI
&lt;/h3&gt;

&lt;p&gt;This page is going to be the clone of the New Post page; we will replace the Submit button with the update button and will add another button for deleting the selected post. Let's go!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's go to the &lt;strong&gt;New Post&lt;/strong&gt; page and select the container. Press &lt;code&gt;ctrl/cmnd+c&lt;/code&gt;, go back to the &lt;strong&gt;Edit Post&lt;/strong&gt; page and press &lt;code&gt;ctrl/cmnd+v&lt;/code&gt;, doing this will clone the container entirely including the nested components from the New Post page.&lt;/li&gt;
&lt;li&gt;Change the Title from &lt;code&gt;New Post&lt;/code&gt; to &lt;code&gt;Edit Post&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Set the &lt;strong&gt;default values&lt;/strong&gt; of the following input components:

&lt;ul&gt;
&lt;li&gt;Default Value for Title's text input : &lt;code&gt;{{queries.posts.data.filter(post =&amp;gt; post._id == variables.selectedListViewIndex)[0].title}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Default Value for Subtitle's text input : &lt;code&gt;{{queries.posts.data.filter(post =&amp;gt; post._id == variables.selectedListViewIndex)[0].subtitle}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Default Value for Content's text area : &lt;code&gt;{{queries.posts.data.filter(post =&amp;gt; post._id == variables.selectedListViewIndex)[0].content}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Default Value for Cover Image's text input: &lt;code&gt;{{queries.posts.data.filter(post =&amp;gt; post._id == variables.selectedListViewIndex)[0].cover}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Default Value for Author's dropdown component: &lt;code&gt;{{queries.posts.data.filter(post =&amp;gt; post._id == variables.selectedListViewIndex)[0].author_name}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Option Value for Author's dropdown component: &lt;code&gt;{{queries.authors.data.map(i =&amp;gt; i.author_name)}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Option Labels for Author's dropdown component: &lt;code&gt;{{queries.authors.data.map(i =&amp;gt; i.author_name)}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Default Value for Tag's dropdown component: &lt;code&gt;{{queries.posts.data.filter(post =&amp;gt; post._id == variables.selectedListViewIndex)[0].tag_name}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Option Value for Tag's dropdown component: &lt;code&gt;{{queries.tags.data.map(i =&amp;gt; i.tag)}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Option Labels for Tag's dropdown component: &lt;code&gt;{{queries.tags.data.map(i =&amp;gt; i.tag)}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-6.07.41-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-6.07.41-PM.png" alt="editpost" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's go to &lt;strong&gt;Submit&lt;/strong&gt; button and change the button text to &lt;strong&gt;Update&lt;/strong&gt;. We will keep both the event handlers as it is and will replace the query in the Run Query handler later once we build the query.&lt;/li&gt;
&lt;li&gt;Copy the &lt;strong&gt;Back&lt;/strong&gt; button from the top and paste it below next to the &lt;strong&gt;Update&lt;/strong&gt; button. Change the button text to &lt;strong&gt;Delete&lt;/strong&gt;. We will add the event handler in the next section when we create the query. Go to the &lt;strong&gt;Styles&lt;/strong&gt;, change the button text and border color to red.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-6.11.57-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-6.11.57-PM.png" alt="backui" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The UI of the Edit Post section is finished. We also updated the default values of the components so that whenever a listItem is clicked from the homepage the details of the selected blog details get updated on the edit page field values.  &lt;/p&gt;
&lt;h3&gt;
  
  
  Edit post: queries
&lt;/h3&gt;
&lt;h4&gt;
  
  
  delete_post
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Create a new query from the query panel, and name it &lt;code&gt;delete_post&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select the &lt;code&gt;Find one and delete&lt;/code&gt; &lt;strong&gt;Operation&lt;/strong&gt; from the dropdown options and then enter the &lt;strong&gt;Collection&lt;/strong&gt; name as &lt;code&gt;posts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Filter&lt;/strong&gt; field value enter:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{queries.posts.data.filter(post =&amp;gt; post._id == variables.selectedListViewIndex)[0].title}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Scroll to the bottom, add an event handler to &lt;strong&gt;run the query&lt;/strong&gt; on the &lt;strong&gt;Query Success&lt;/strong&gt; event and select the &lt;code&gt;posts&lt;/code&gt; query and then &lt;strong&gt;Save&lt;/strong&gt; the query.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-6.45.23-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-6.45.23-PM.png" alt="querysucces" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  update_post
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Create another MongoDB query from the query panel, and name it &lt;code&gt;update_post&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select the &lt;code&gt;Find one and update&lt;/code&gt; &lt;strong&gt;Operation&lt;/strong&gt; from the dropdown options and then enter the &lt;strong&gt;Collection&lt;/strong&gt; name as &lt;code&gt;posts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Filter&lt;/strong&gt; field value enter:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{queries.posts.data.filter(post =&amp;gt; post._id == variables.selectedListViewIndex)[0].title}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;In the &lt;strong&gt;Update&lt;/strong&gt; field value enter:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;$set&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.textinput1.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;subtitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.textinput2.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.richtexteditor1.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.textinput3.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;author_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.dropdown1.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;tag_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.dropdown2.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-6.49.22-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-6.49.22-PM.png" alt="js" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scroll to the bottom, add an event handler to &lt;strong&gt;run the query&lt;/strong&gt; on the &lt;strong&gt;Query Success&lt;/strong&gt; event, and select the &lt;strong&gt;posts&lt;/strong&gt; query and then &lt;strong&gt;Save&lt;/strong&gt; the query.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-17-at-6.51.20-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-17-at-6.51.20-PM.png" alt="runthequery" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Edit post: Connecting queries data to UI
&lt;/h3&gt;

&lt;p&gt;Now, all we need to do is update the event handlers on the Update and Delete buttons.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the &lt;strong&gt;handle&lt;/strong&gt; of the &lt;strong&gt;Delete&lt;/strong&gt; button to edit its &lt;strong&gt;properties&lt;/strong&gt;. Go to &lt;strong&gt;Events&lt;/strong&gt;, and change the query in the Run Query event to &lt;code&gt;delete_post&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-7.00.06-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-17-at-7.00.06-PM.png" alt="editpostconnnect" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Similarly, we will update the event handler of the &lt;strong&gt;Update&lt;/strong&gt; button. Open its properties, go to Events, and change the query in the &lt;strong&gt;Run Query&lt;/strong&gt; event to update_post&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-17-at-7.00.36-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-17-at-7.00.36-PM.png" alt="runqueryui" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  View post: UI
&lt;/h3&gt;

&lt;p&gt;This page will be loaded when the 👁️/view button is clicked next to the item in the listview on the All Posts page. Let's build the UI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the home page/All Posts page and click on the 👁️/view post button next to the list item to load the &lt;code&gt;view_post&lt;/code&gt; page&lt;/li&gt;
&lt;li&gt;Once the &lt;code&gt;view_post&lt;/code&gt; page is loaded, drag a &lt;strong&gt;container&lt;/strong&gt; component onto the canvas. Expand the container completely both vertically and horizontally to fit the entire canvas.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to either of the page &lt;code&gt;New Post&lt;/code&gt; or &lt;code&gt;Edit Post&lt;/code&gt;, copy the back button and paste it on the &lt;code&gt;view_post&lt;/code&gt; page. Drag a &lt;strong&gt;divider&lt;/strong&gt; component below the button.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-2.36.32-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-2.36.32-PM.png" alt="dragcontainer" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now let's drag the following components and set their properties and styles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;text component for showing the Title: text = &lt;code&gt;{{queries.posts.data.filter(post =&amp;gt; post._id == variables.selectedListViewIndex)[0].title}}&lt;/code&gt; , font weight = bold, font size = 16&lt;/li&gt;
&lt;li&gt; text component for showing the Subtitle: text = &lt;code&gt;{{queries.posts.data.filter(post =&amp;gt; post._id == variables.selectedListViewIndex)[0].subtitle}}&lt;/code&gt; , font weight = bold, font size = 15&lt;/li&gt;
&lt;li&gt;  text component for showing the Author: text = Author: &lt;code&gt;{{queries.posts.data.filter(post =&amp;gt; post._id == variables.selectedListViewIndex)[0].author_name}}&lt;/code&gt; , font weight = bold, font size = 14&lt;/li&gt;
&lt;li&gt;image component for displaying the Cover Image: URL = &lt;code&gt;{{queries.posts.data.filter(post =&amp;gt; post._id == variables.selectedListViewIndex)[0].cover}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;text component for showing Content: text = &lt;code&gt;{{queries.posts.data.filter(post =&amp;gt; post._id == variables.selectedListViewIndex)[0].content}}&lt;/code&gt; , font weight = normal, font size = 14
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-3.15.51-PM.png" alt="componentsvalues" width="800" height="400"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  View post: Queries
&lt;/h3&gt;

&lt;p&gt;This page doesn't requires any queries. The data on this page is loaded using the queries that we created previously.&lt;/p&gt;
&lt;h3&gt;
  
  
  View post: Connecting queries data to UI
&lt;/h3&gt;

&lt;p&gt;We have already connected the data while building the UI. We are using variables that we created previously to filter the data according the clicked list item.&lt;br&gt;
For ex: for loading the Title of the selected list view item we have set the value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;queries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selectedListViewIndex&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Authors &amp;amp; Tags: UI
&lt;/h3&gt;

&lt;p&gt;We are finally at the last page of the application. In this page we are going to display the list of all the author and all the tags. From this page we can perform CRUD operations on &lt;code&gt;authors&lt;/code&gt; and &lt;code&gt;tags&lt;/code&gt; collection in database. Let's build the UI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the homepage/All Posts page of the application and click on the &lt;code&gt;Authors &amp;amp; Tags&lt;/code&gt; button on the page, this will redirect you to the &lt;code&gt;authors_tags&lt;/code&gt; page&lt;/li&gt;
&lt;li&gt;Drag a &lt;strong&gt;container&lt;/strong&gt; onto the canvas and resize(both vertically and horizontally) it to fit the canvas. Copy the &lt;strong&gt;back button&lt;/strong&gt; from any of the other pages and paste it on the top-right of this page&lt;/li&gt;
&lt;li&gt;Let's add two text components use html tags to make them into Title: &lt;strong&gt;Authors, Tags&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Add two &lt;strong&gt;divider&lt;/strong&gt; components below the titles and two tables respectively.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-3.48.00-PM.png" alt="authorsandtagsui" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now, we will be adding two buttons, one for adding the authors into the database and the other for adding tags into the database. We can copy the New Post button from the home page to keep the styling same. Remove the event handlers and change the button text to &lt;strong&gt;+Add&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-3.50.58-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-3.50.58-PM.png" alt="add" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Drag &lt;strong&gt;three modals&lt;/strong&gt; somewhere below the container. These modals will be shown when the following buttons are clicked: &lt;strong&gt;+Add&lt;/strong&gt; button for &lt;strong&gt;Authors&lt;/strong&gt;, &lt;strong&gt;+Add&lt;/strong&gt; button for &lt;strong&gt;tags&lt;/strong&gt;, and &lt;strong&gt;View action&lt;/strong&gt; button on &lt;strong&gt;Authors&lt;/strong&gt; table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Toggle off&lt;/strong&gt; the &lt;code&gt;Use default trigger button&lt;/code&gt; for all the three modals.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-4.35.06-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-4.35.06-PM.png" alt="modalui" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go to the &lt;strong&gt;properties&lt;/strong&gt; of &lt;strong&gt;+Add&lt;/strong&gt; button for &lt;strong&gt;Authors&lt;/strong&gt;, add an &lt;strong&gt;event handler&lt;/strong&gt; to show the &lt;strong&gt;modal1&lt;/strong&gt;. Click on the button to show the &lt;strong&gt;modal1&lt;/strong&gt;. Once the modal loads click somewhere outside the modal, then drag the components from the components library onto the modal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3 text components: Author Name, Author Email, and Author Image&lt;/li&gt;
&lt;li&gt;3 text input components : name, email, image URL&lt;/li&gt;
&lt;li&gt;A button component for triggering the query that we will create in the next section, set the button text to &lt;code&gt;Add&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-4.50.05-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-4.50.05-PM.png" alt="modal1ui" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Just like the &lt;strong&gt;+Add&lt;/strong&gt; button for Authors, we are going to add an event handler on the +Add button for tags to trigger &lt;strong&gt;modal2&lt;/strong&gt;, open the modal and add the following components inside the modal:

&lt;ul&gt;
&lt;li&gt;1 text input components: &lt;strong&gt;Tag&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A button component for triggering the queries that we will create in the next section, set the button text to &lt;strong&gt;Add Tag&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-5.01.38-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-5.01.38-PM.png" alt="modal2" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Go to the &lt;strong&gt;Authors&lt;/strong&gt; Table, add two &lt;strong&gt;Action buttons:  View and Remove&lt;/strong&gt;. On View action button, we will add an event handler to show the &lt;strong&gt;modal3&lt;/strong&gt; and the Remove action button will trigger the query that will remove the selected author from the collection.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-5.08.38-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-5.08.38-PM.png" alt="modal3" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on the &lt;strong&gt;View&lt;/strong&gt; button to show the modal, add components inside the modal3 just like we have added components in the previous 2 modals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2 text components: text = &lt;code&gt;{{components.table1.selectedRow.author_name}}&lt;/code&gt; &amp;amp; &lt;code&gt;{{components.table1.selectedRow.author_email}}&lt;/code&gt;, keep the font weight = bold for the first text component.&lt;/li&gt;
&lt;li&gt;1 image component to display the author image: &lt;code&gt;{{components.table1.selectedRow.author_image}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Go to the &lt;strong&gt;Tags&lt;/strong&gt; Table, and add one &lt;strong&gt;Action button:  Delete&lt;/strong&gt;. This action button will trigger the query that will remove the selected tag from the collection.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-5.09.11-PM-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-5.09.11-PM-1.png" alt="tagstable" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Authors &amp;amp; Tags: Queries
&lt;/h3&gt;

&lt;h4&gt;
  
  
  add_authors
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Create a new MongoDB query, name it &lt;code&gt;add_author&lt;/code&gt;, select &lt;code&gt;insert one&lt;/code&gt; from the &lt;strong&gt;operations&lt;/strong&gt; dropdown, and enter &lt;code&gt;authors&lt;/code&gt; in the collection field.&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Document&lt;/strong&gt; field, enter:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;author_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.textinput1.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;author_email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.textinput2.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;author_image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.textinput3.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Go to the bottom, and add an &lt;strong&gt;event handler&lt;/strong&gt; to run &lt;strong&gt;authors&lt;/strong&gt; query on &lt;strong&gt;Query Success Event&lt;/strong&gt;. Finally, &lt;strong&gt;Save&lt;/strong&gt; the query.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-6.06.51-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-6.06.51-PM.png" alt="querysuccessevent" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  add_tags
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Create a new MongoDB query, name it &lt;code&gt;add_tag&lt;/code&gt;, select &lt;code&gt;insert one&lt;/code&gt; from the &lt;strong&gt;operations&lt;/strong&gt; dropdown, and enter &lt;code&gt;tags&lt;/code&gt; in the collection field.&lt;/li&gt;
&lt;li&gt;In the Document field, enter:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.textinput4.value}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Go to the bottom, and add an &lt;strong&gt;event handler&lt;/strong&gt; to run tags query on &lt;strong&gt;Query Success&lt;/strong&gt; Event. Finally, &lt;strong&gt;Save&lt;/strong&gt; the query.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-6.11.23-PM.png" alt="savethequery" width="800" height="400"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  delete_author
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Create a new MongoDB query, name it &lt;code&gt;delete_author&lt;/code&gt;, select &lt;code&gt;delete one&lt;/code&gt; from the &lt;strong&gt;operations&lt;/strong&gt; dropdown, and enter &lt;code&gt;authors&lt;/code&gt; in the &lt;strong&gt;collection&lt;/strong&gt; field.&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Filter&lt;/strong&gt; field, enter:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;author_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.table1.selectedRow.author_name}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Go to the bottom, and add an event handler to run &lt;code&gt;authors&lt;/code&gt; query on &lt;code&gt;Query Success&lt;/code&gt; Event. Finally, &lt;strong&gt;Save&lt;/strong&gt; the query.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-6.26.48-PM.png" alt="deleteauthorquery" width="800" height="400"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  delete_tag
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Create a new MongoDB query, name it &lt;code&gt;delete_tag&lt;/code&gt;, select &lt;code&gt;delete one&lt;/code&gt; from the &lt;strong&gt;operations&lt;/strong&gt; dropdown, and enter &lt;code&gt;tags&lt;/code&gt; in the &lt;strong&gt;collection&lt;/strong&gt; field.&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Filter&lt;/strong&gt; field, enter:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tag&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{components.table2.selectedRow.tag}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Go to the bottom, and add an &lt;strong&gt;event handler&lt;/strong&gt; to run &lt;code&gt;authors&lt;/code&gt; query on &lt;strong&gt;Query Success&lt;/strong&gt; Event. Finally, &lt;strong&gt;Save&lt;/strong&gt; the query.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-6.28.03-PM.png" alt="deletetagquery" width="800" height="400"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Authors &amp;amp; Tags: Connecting queries data to UI
&lt;/h3&gt;

&lt;p&gt;Let's connect the queries to the table components to display the data and the button components for triggering the insert and delete queries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;Author's&lt;/strong&gt; table, edit its &lt;strong&gt;properties&lt;/strong&gt;, and set &lt;strong&gt;table data&lt;/strong&gt; to &lt;code&gt;{{queries.authors.data}}&lt;/code&gt; . The columns will be &lt;strong&gt;auto-populated&lt;/strong&gt;. Enable the &lt;strong&gt;highlight selected row&lt;/strong&gt; from the options and set the &lt;strong&gt;loading state&lt;/strong&gt; of the table to &lt;code&gt;{{queries.delete_author.isLoading || queries.authors.isLoading}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Edit &lt;strong&gt;Remove&lt;/strong&gt; action button and add the &lt;strong&gt;event handler&lt;/strong&gt; to run the &lt;code&gt;delete_author&lt;/code&gt; query. This will remove the author from the database whenever the action button is clicked.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-6.37.06-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-6.37.06-PM.png" alt="connectingauthorstags" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the &lt;strong&gt;+Add&lt;/strong&gt; Authors button to show the modal, inside modal, there is a &lt;strong&gt;Add button&lt;/strong&gt; for submitting the form. Add the following event handlers to this button:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1st event handler&lt;/strong&gt; to run the query: &lt;code&gt;add_author&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;next 3 event handlers&lt;/strong&gt; to &lt;code&gt;control the component&lt;/code&gt;. Components will be the three text inputs that are there in the modal and the Action will be Clear . Adding these event handlers will clear the form as soon as the &lt;code&gt;add_author&lt;/code&gt; query is triggered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;last&lt;/strong&gt; event handler for &lt;strong&gt;closing the modal&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-6.43.27-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-6.43.27-PM.png" alt="eventhandlers" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, we are going to add the event handlers to +Add button for the Tags:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1st event handler&lt;/strong&gt; to run the query: &lt;code&gt;add_tag&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;next event handler&lt;/strong&gt; to &lt;strong&gt;control the component&lt;/strong&gt;. Select the text input component that is there in the form and set the Action to &lt;code&gt;Clear&lt;/code&gt; .&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;last&lt;/strong&gt; event handler for &lt;strong&gt;closing the modal&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-6.46.07-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-6.46.07-PM.png" alt="closingthemodal" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finally, go to the &lt;strong&gt;Tags&lt;/strong&gt; table, and set the &lt;strong&gt;table data&lt;/strong&gt; to &lt;code&gt;{{queries.tags.data}}&lt;/code&gt; . The columns will be &lt;strong&gt;auto-populated&lt;/strong&gt;. Enable the &lt;strong&gt;highlight selected row&lt;/strong&gt; from the options and set the &lt;strong&gt;loading state&lt;/strong&gt; of the table to &lt;code&gt;{{queries.delete_tag.isLoading || queries.tag.isLoading}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Edit &lt;strong&gt;delete&lt;/strong&gt; action button and add the event handler to run the &lt;code&gt;delete_tag&lt;/code&gt; query.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-6.48.01-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-20-at-6.48.01-PM.png" alt="loadingstate" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Connecting to NextJS app
&lt;/h2&gt;

&lt;p&gt;Using the connection string, we can connect the MongoDB Atlas database to any NextJS app. In this section, we will locally set up a NextJS application and then connect it to the MongoDB database to load the data on the front end.&lt;/p&gt;

&lt;h3&gt;
  
  
  Requirements:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MongoDB Atlas database&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NodeJS 12+&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;npm and npx&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vercel (Optional if you want to deploy your NextJS app)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Building NextJS app
&lt;/h3&gt;

&lt;p&gt;Go to the terminal, and enter the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app &lt;span class="nt"&gt;--example&lt;/span&gt; with-mongodb nextblog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are using the &lt;code&gt;npx create-next-app&lt;/code&gt; command and are passing the &lt;code&gt;--example with-mongodb&lt;/code&gt; parameter which will tell &lt;code&gt;create-next-app&lt;/code&gt; to bootstrap our app with the MongoDB integration example. Finally, &lt;code&gt;nextblog&lt;/code&gt; is the name of our application.&lt;/p&gt;

&lt;p&gt;Executing this command will take a couple of seconds to download and install all the npm dependencies, but once they're downloaded and installed, navigate to your project directory by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;nextblog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install all the npm dependencies by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's start up our application. To start our Next.js app, execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the app is built successfully, we can navigate to &lt;code&gt;localhost:3000&lt;/code&gt; to see our app live in action.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-21-at-4.25.45-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-21-at-4.25.45-AM.png" alt="localhost1" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will get an error similar to the one in the screenshot above because the app is built but we haven't connected our MongoDB database yet to the application. So let's do that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connecting MongoDB
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;On the &lt;code&gt;nextblog&lt;/code&gt; directory, we can find the &lt;code&gt;env.local.example&lt;/code&gt; file. We can rename the file to &lt;code&gt;env.local&lt;/code&gt; and then edit it.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In this file, we will need to enter the value for &lt;code&gt;MONGODB_URI&lt;/code&gt; and &lt;code&gt;MONGODB_DB&lt;/code&gt; variable. &lt;code&gt;MONGODB_URI&lt;/code&gt; is nothing but the connection string till / and &lt;code&gt;MONGODB_DB&lt;/code&gt; will be the name of the database. Go to the beginning of the tutorial to learn how we can obtain the connection string from the Atlas. The &lt;code&gt;env.local&lt;/code&gt; file will look like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-21-at-4.34.44-AM-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2023%2F03%2FScreenshot-2023-03-21-at-4.34.44-AM-1.png" alt="envfile" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As soon as you save these environment variables, go to the browser and you'll see that the error is gone and &lt;code&gt;with-mongodb&lt;/code&gt; Next.js app welcome page is loaded.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-21-at-4.39.58-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-21-at-4.39.58-AM.png" alt="welcome" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Querying MongoDB with Next.js
&lt;/h3&gt;

&lt;p&gt;The first example we'll look at is building and exposing an API endpoint in our Next.js application. To create a new &lt;code&gt;API&lt;/code&gt; endpoint route, we will first need to create an api directory in our &lt;code&gt;pages&lt;/code&gt; directory, and then every file we create in this &lt;code&gt;api&lt;/code&gt; directory will be treated as an individual API endpoint.&lt;/p&gt;

&lt;p&gt;Let's go ahead and create the &lt;code&gt;api&lt;/code&gt; directory and a new file in this &lt;code&gt;directory&lt;/code&gt; called &lt;code&gt;posts.js&lt;/code&gt;. This endpoint will return a list of all the blog posts from our &lt;code&gt;posts&lt;/code&gt; collection in the MongoDB database. The implementation for this route is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;connectToDatabase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../lib/mongodb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;connectToDatabase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({}).&lt;/span&gt;&lt;span class="nf"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go to the &lt;code&gt;lib/mongodb.ts&lt;/code&gt; file and update the existing code to the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MongoClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongodb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MONGODB_URI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MONGODB_DB&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;MONGODB_URI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Please define the MONGODB_URI environment variable inside .env.local&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;MONGODB_DB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Please define the MONGODB_DB environment variable inside .env.local&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Global is used here to maintain a cached connection across hot reloads
 * in development. This prevents connections growing exponentially
 * during API Route usage.
 */&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;cached&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mongo&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cached&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mongo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;connectToDatabase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;conn&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;useNewUrlParser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;useUnifiedTopology&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;MongoClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MONGODB_URI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;db&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MONGODB_DB&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;conn&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if we navigate to &lt;code&gt;localhost:3000/api/posts&lt;/code&gt;, we'll see a result that looks like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-21-at-5.06.41-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-21-at-5.06.41-AM.png" alt="localhost2" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, let's update the &lt;code&gt;pages/index.ts&lt;/code&gt; file to use this JSON response and display the formatted data on the homepage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Head&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/head&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;connectToDatabase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../lib/mongodb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;InferGetServerSidePropsType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getServerSideProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;connectToDatabase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({}).&lt;/span&gt;&lt;span class="nf"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allposts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;allposts&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Nextbnb&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/title&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;icon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/favicon.ico&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stylesheet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Head&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;md:container md:mx-auto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;All&lt;/span&gt; &lt;span class="nx"&gt;Posts&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;by&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;author_name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;published_on&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="p"&gt;))&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, navigate to &lt;code&gt;http://localhost:3000/&lt;/code&gt; !&lt;/p&gt;

&lt;p&gt;Tada 🎉 Now you can see the &lt;code&gt;posts&lt;/code&gt; collection data on the homepage of the application. This is just the rough presentation of the data on the frontend - you can make further changes to improve the UI.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-21-at-5.15.52-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2023%2F03%2FScreenshot-2023-03-21-at-5.15.52-AM.png" alt="collectionpost" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Putting it all together
&lt;/h3&gt;

&lt;p&gt;In this tutorial, we walked through the MongoDB Atlas and created a database with three different collections, learned how to quickly build a multipage application using ToolJet, and finally, we connected our MongoDB database to the Next.js application and executed queries.&lt;/p&gt;

&lt;p&gt;If you have any questions or feedback, reach out through the &lt;a href="https://tooljet.com/slack" rel="noopener noreferrer"&gt;ToolJet Slack community&lt;/a&gt; and let me know what you want to build with ToolJet and MongoDB.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tooljet</category>
      <category>mongodb</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Build a Ticket Triaging App with Baserow and ToolJet</title>
      <dc:creator>Shubhendra Singh Chauhan</dc:creator>
      <pubDate>Thu, 22 Sep 2022 11:03:10 +0000</pubDate>
      <link>https://forem.com/tooljet/build-a-ticket-triaging-app-with-baserow-and-tooljet-250</link>
      <guid>https://forem.com/tooljet/build-a-ticket-triaging-app-with-baserow-and-tooljet-250</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In this tutorial, we will learn how to build an application for internal tickets triaging and for this we will be leveraging the power of Baserow for the backend and ToolJet for the frontend of the application.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://baserow.io/" rel="noopener noreferrer"&gt;Baserow&lt;/a&gt; is an open-source no-code database and the Airtable alternative. It can be used to build an online database without technical experience and can be easily used as the backend but creating a custom UI can be challenging. That's where &lt;a href="https://www.tooljet.com/" rel="noopener noreferrer"&gt;ToolJet&lt;/a&gt; comes into action, it is a free and &lt;a href="https://github.com/ToolJet/ToolJet" rel="noopener noreferrer"&gt;open-source&lt;/a&gt; low-code platform that allows you to quickly build applications and has more than 30+ datasources including Baserow that will let you seamlessly perform operations on your database. You can create a free account on &lt;a href="https://www.tooljet.com/" rel="noopener noreferrer"&gt;ToolJet Cloud&lt;/a&gt; or run it on your &lt;a href="https://docs.tooljet.com/docs/setup/" rel="noopener noreferrer"&gt;local machine&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this tutorial, we will build a Ticket Triaging application. This is going to be a simple and easy tutorial, you can use refer to this tutorial to build dashboards, CRUD apps, and internal tools in minutes using the Baserow and ToolJet combination.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With the Ticket Triaging app, you can:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;List the issues, check their status and assignees&lt;/li&gt;
&lt;li&gt;Update the status of the issue/bug&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 You can also add more functionality to the application by adding a form in the application to add an issue or a button to delete an issue, making it a CRUD app.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can try out the application here: &lt;a href="https://apps.tooljet.com/ticket-triaging-app" rel="noopener noreferrer"&gt;https://apps.tooljet.com/ticket-triaging-app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F09%2FSep-19-2022-16-38-05.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F09%2FSep-19-2022-16-38-05.gif" alt="demo" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't want to read the tutorial and want to jump straight into using the app?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Import the exported application JSON file to your ToolJet account. Here's the &lt;a href="https://blog.tooljet.com/content/files/2022/09/ticket-triaging-export-1663582948129.json" rel="noopener noreferrer"&gt;file&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Once imported the application, you'll need to provide the &lt;strong&gt;API Token&lt;/strong&gt; and choose the host &lt;strong&gt;Baserow Cloud or Baserow Self-Hosted&lt;/strong&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F09%2FScreenshot-2022-09-20-at-4.54.53-PM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;You can get the &lt;strong&gt;API key&lt;/strong&gt; from the &lt;strong&gt;Personal API tokens&lt;/strong&gt; in &lt;strong&gt;Settings&lt;/strong&gt; of the Baserow
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-20-at-4.53.12-PM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;Here's the &lt;a href="https://baserow.io/templates/software-application-bug-tracker" rel="noopener noreferrer"&gt;Software Application Bug Tracker&lt;/a&gt; template that I used as the database to build this application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without further ado, let's start building the application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building the UI of the application
&lt;/h2&gt;

&lt;p&gt;Let's start with building the UI first. Login to ToolJet and then on the &lt;strong&gt;Dashboard&lt;/strong&gt;, click on the &lt;strong&gt;Create new application&lt;/strong&gt; button to create a new app. Once the app is created, you will be redirected to the visual app builder. You can change the name of the app by editing the default name i.e &lt;strong&gt;Untitled app&lt;/strong&gt; from the top left of the app builder.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2021%2F12%2Flogin-1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2021%2F12%2Flogin-1.gif" alt="tooljet" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The visual app builder has 4 sections:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Canvas&lt;/strong&gt; is at the center, where you'll drag and drop widgets to build UI.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.tooljet.com/docs/tutorial/building-queries" rel="noopener noreferrer"&gt;Query Manager&lt;/a&gt; at the bottom, where you can create and manage queries.&lt;/li&gt;
&lt;li&gt;On the right sidebar, you'll find the &lt;a href="https://docs.tooljet.com/docs/tutorial/adding-widget/" rel="noopener noreferrer"&gt;Components Drawer&lt;/a&gt; which has a list of built-in components. You can drag and drop to start building out the user interface.&lt;/li&gt;
&lt;li&gt;On the left sidebar, you'll see the Inspector, debugger, comments, settings, and &lt;a href="https://docs.tooljet.com/docs/tutorial/adding-a-datasource" rel="noopener noreferrer"&gt;Datasource manager&lt;/a&gt;. The datasource manager is used to add a new datasource or manage the connected datasources.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Let's build the UI
&lt;/h3&gt;

&lt;p&gt;For building the user interface, you’ll need to drag and drop the following components from the Components Drawer(right sidebar) and place them accordingly.&lt;/p&gt;

&lt;p&gt;Here is the configuration of widgets that I used for building the user interface:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;Container&lt;/strong&gt; as header and &lt;strong&gt;Text&lt;/strong&gt; widget inside the container to give a title to the app i.e &lt;strong&gt;Ticket Triaging System&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;For the &lt;strong&gt;Header&lt;/strong&gt; text, you can use &lt;strong&gt;HTML&lt;/strong&gt; tags for the formatting of the text along with the other Styles options available in the component editor
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-12.36.08-PM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;Now drag a &lt;strong&gt;Tabs&lt;/strong&gt; component right below the header, and set the value of the following tabs:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{{[&lt;/span&gt; 
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'Issues 📋', id: '0' }, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'Review and Triage 🔍', id: '1' }, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
 &lt;span class="p"&gt;]}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-12.49.24-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-12.49.24-PM.png" alt="tooljet" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Drag containers inside the &lt;strong&gt;Issues&lt;/strong&gt; and &lt;strong&gt;Review &amp;amp; Triage&lt;/strong&gt; tabs individually and set the background color for both containers
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-12.50.32-PM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;On the Issues tab, add a &lt;strong&gt;chart&lt;/strong&gt; component on the right side. Edit Chart's properties and set the chart type as &lt;strong&gt;pie&lt;/strong&gt; and chart data to &lt;code&gt;{{queries.issues.data.chartData}}&lt;/code&gt; - it might throw an error in the debugger as we haven't created any queries yet.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-1.10.33-PM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;On the left side of the Issues tab, add a &lt;strong&gt;table&lt;/strong&gt; component and set the &lt;strong&gt;table data&lt;/strong&gt; value to &lt;code&gt;{{queries.issues.data.results}}&lt;/code&gt; - the data will show up when we build the queries later in this tutorial.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-1.36.04-PM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;let's add the following columns to the table

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;Id&lt;/code&gt; , key: &lt;code&gt;id&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Name: &lt;code&gt;Bug&lt;/code&gt; , key: &lt;code&gt;Bug&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Name: &lt;code&gt;Status&lt;/code&gt; , key: &lt;code&gt;Status.value&lt;/code&gt; , Text color: &lt;code&gt;{{cellValue === "Assigned" ? "green" : cellValue === "Closed" ? "red" : "orange"}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Name: &lt;code&gt;Severity level&lt;/code&gt; , key: &lt;code&gt;Severity level[0].value&lt;/code&gt; , Text color: &lt;code&gt;{{cellValue === "Level 3 - critical" ? "red" : cellValue === "Level 2 - major" ? "orange" : "green" }}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Name: &lt;code&gt;Date reported&lt;/code&gt; , key: &lt;code&gt;Date reported&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Name: &lt;code&gt;Assigned to&lt;/code&gt; , key: &lt;code&gt;Assigned to[0].value&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-2.50.01-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-2.50.01-PM.png" alt="tooljet" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's also add an &lt;strong&gt;action&lt;/strong&gt; button on the table so that the users can click on the action button to open the details about the selected issue. We will add an &lt;strong&gt;event handler&lt;/strong&gt; to the action button to &lt;strong&gt;control the tab component&lt;/strong&gt; and change the current tab to &lt;code&gt;Review &amp;amp; Triage&lt;/code&gt;(id 1).
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-2.53.00-PM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;Enable the &lt;strong&gt;highlight selected row&lt;/strong&gt; option in the table.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's switch to &lt;strong&gt;Review and Triage&lt;/strong&gt; tab and add components. In this tab we will need to create 5 sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Issue Details&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Assignee Details&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Code Files&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;File Info&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Triage Issue&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's start with the &lt;strong&gt;Issue details&lt;/strong&gt; section first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a &lt;strong&gt;container&lt;/strong&gt; and resize it as shown in the screenshot.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-4.26.42-PM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;Add a text widget on the top of the container and set its value to &amp;lt;h1&amp;gt; 📝 Issue detail &amp;lt;/h1&amp;gt; and then drop a &lt;strong&gt;divider&lt;/strong&gt; below it. You can also change the text color from the Styles tab.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-4.27.55-PM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;Next, we will add the &lt;strong&gt;text&lt;/strong&gt; widgets inside this container to display the issue details:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Issue&lt;/strong&gt; (bold it from the styles) and then add another text widget to the right of the issue and set its value to &lt;code&gt;{{components.table1.selectedRow.Bug}}&lt;/code&gt;.Here we are picking up the data from the database with reference to the selected row in the table.&lt;/li&gt;
&lt;li&gt;Now add other text widgets accordingly; &lt;strong&gt;Date Reported&lt;/strong&gt; - &lt;code&gt;{{components.table1.selectedRow['Date reported']}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status&lt;/strong&gt; - &lt;code&gt;{{components.table1.selectedRow.Status.value}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Severity level&lt;/strong&gt; - &lt;code&gt;{{components.table1.selectedRow['Severity level'][0].value}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Current behavior&lt;/strong&gt; - &lt;code&gt;{{components.table1.selectedRow['Current behavior']}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expected behavior&lt;/strong&gt; - &lt;code&gt;{{components.table1.selectedRow['Expected behavior']}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-4.41.37-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-4.41.37-PM.png" alt="tooljet" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Did you notice there is a text &lt;strong&gt;Please select an issue from the issues tab&lt;/strong&gt; - it is only visible when the user doesn't click on any issue on the table. You can set a condition on the &lt;strong&gt;Visibility&lt;/strong&gt; property of this text widget to only show when a row is clicked. Set the value to &lt;code&gt;{{_.isEmpty(components.table1.selectedRow)}}&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 ToolJet allows you to internally utilize the Moment, Lodash, and Axios libraries.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, the &lt;strong&gt;Issue details&lt;/strong&gt; section is done. Similarly, we will build other sections. Let's build the &lt;strong&gt;Assignee Details&lt;/strong&gt; section:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We will be quickly creating this section by simply copy-pasting the &lt;strong&gt;Issue Details&lt;/strong&gt; section. Select the Issue details container and press c*&lt;em&gt;trl/cmnd+c&lt;/em&gt;* and then press &lt;strong&gt;ctrl/cmnd+v&lt;/strong&gt; to duplicate the whole section. Now place it next to the Issue details section and make the required changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Check out all the shortcuts supported in ToolJet &lt;a href="https://docs.tooljet.com/docs/tutorial/keyboard-shortcuts" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-5.41.44-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-5.41.44-PM.png" alt="tooljet" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At the top of this section add an &lt;strong&gt;image&lt;/strong&gt; component and set the value to &lt;code&gt;{{queries.team.data.results.filter(x =&amp;gt; x.id === components.table1.selectedRow['Assigned to'][0].id)[0].Photo[0].url}}&lt;/code&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-5.48.58-PM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;Let's add the text components with the following values:

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Name&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Role&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skills&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Authored code&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Code files worked on&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Add &lt;strong&gt;text&lt;/strong&gt; components next to the components in the previous step and set the value to:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;{{queries.team.data.results.filter(x =&amp;gt; x.id === components.table1.selectedRow['Assigned to'][0].id)[0].Name}}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{{queries.team.data.results.filter(x =&amp;gt; x.id === components.table1.selectedRow['Assigned to'][0].id)[0].Role.value}}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{{queries.team.data.results.filter(x =&amp;gt; x.id === components.table1.selectedRow['Assigned to'][0].id)[0]['Programming languages'].map(i =&amp;gt; i.value)}}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{{queries.team.data.results.filter(x =&amp;gt; x.id === components.table1.selectedRow['Assigned to'][0].id)[0]['Authored code'].map(i =&amp;gt; i.value)}}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{{queries.team.data.results.filter(x =&amp;gt; x.id === components.table1.selectedRow['Assigned to'][0].id)[0]['Code file(s) worked on'].map(i =&amp;gt; i.value)}}&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-5.49.35-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-5.49.35-PM.png" alt="tooljet" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Assignee details section is finished, let's move on to the next section which is &lt;strong&gt;Code files&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's copy-paste the assignee details section and place it next to each other. Rename the header in this section to &lt;strong&gt;Code Files&lt;/strong&gt; and delete all the text widgets. Just keep the divider and the title.&lt;/li&gt;
&lt;li&gt;Add a &lt;strong&gt;table&lt;/strong&gt; inside the container as shown in the screenshot.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-6.02.13-PM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;Set the &lt;strong&gt;table data&lt;/strong&gt; value as &lt;code&gt;{{components.table1.selectedRow['Related code file(s)']}}&lt;/code&gt; and add two new columns &lt;strong&gt;id&lt;/strong&gt; and &lt;strong&gt;Name&lt;/strong&gt;. Also, enable the &lt;strong&gt;highlight the selected row&lt;/strong&gt; option&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now the Code Files section is done, let's create another section for displaying the details of the selected file in the table of the Code Files section.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy and paste the Assignee Details section as we have done previously in this tutorial. Edit the Title in the header as &lt;strong&gt;File Info&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Edit the values of the text components inside the container accordingly. In this section we need the following details:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Current use&lt;/strong&gt;: &lt;code&gt;{{queries.files.data.results.filter(x =&amp;gt; x.id === components.table2.selectedRow.id)[0]['Current use'].value}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Language&lt;/strong&gt;: &lt;code&gt;{{queries.files.data.results.filter(x =&amp;gt; x.id === components.table2.selectedRow.id)[0]['Programming language'].map(i =&amp;gt; i.value)}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Creator&lt;/strong&gt;: &lt;code&gt;{{queries.files.data.results.filter(x =&amp;gt; x.id === components.table2.selectedRow.id)[0]['Original creator'].map(i =&amp;gt; i.value)}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Function&lt;/strong&gt;: &lt;code&gt;{{queries.files.data.results.filter(x =&amp;gt; x.id === components.table2.selectedRow.id)[0]['Function']}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Path&lt;/strong&gt;: &lt;code&gt;{{queries.files.data.results.filter(x =&amp;gt; x.id === components.table2.selectedRow.id)[0]['Path to source']}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-6.32.12-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-6.32.12-PM.png" alt="tooljet" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, let's build the last section i.e &lt;strong&gt;Triage Issue&lt;/strong&gt;. We can simply use the body of other sections by copy-pasting.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For this section, we need only the &lt;strong&gt;Title&lt;/strong&gt; and &lt;strong&gt;divider&lt;/strong&gt; components. Rename the Title to &lt;code&gt;Triage Issue&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-6.41.55-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-6.41.55-PM.png" alt="tooljet" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Drag a &lt;strong&gt;dropdown&lt;/strong&gt; and a &lt;strong&gt;button&lt;/strong&gt; widget inside the container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Edit the properties of the dropdown component, set the &lt;strong&gt;label&lt;/strong&gt; as &lt;code&gt;Triage&lt;/code&gt; , &lt;strong&gt;default value&lt;/strong&gt; as &lt;code&gt;{{243298}}&lt;/code&gt; , &lt;strong&gt;Option values&lt;/strong&gt; as &lt;code&gt;{{[243296, 243297, 243298]}}&lt;/code&gt; , and &lt;strong&gt;Option labels&lt;/strong&gt; as &lt;code&gt;{{["Assigned", "In progress", "Closed"]}}&lt;/code&gt; . The numbers mentioned in the default value and option values are actually the &lt;strong&gt;ids&lt;/strong&gt; of the single select options in the baserow.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-6.47.57-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-6.47.57-PM.png" alt="tooljet" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a button and name it as &lt;strong&gt;Update&lt;/strong&gt;, set its loading state to &lt;code&gt;{{queries.triage.isLoading}}&lt;/code&gt; so that it shows the loader whenever the triage query is running. We will add an event handler to the button to trigger the triage query later in this tutorial once we build the queries. You can also change the color of the button from the &lt;strong&gt;styles&lt;/strong&gt; tab.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-6.47.57-PM-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-21-at-6.47.57-PM-1.png" alt="tooljet" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Great!!🥳 we are finally done with building the UI of the application. Now let's go ahead and quickly build the queries to make our app fully functional. &lt;/p&gt;




&lt;h2&gt;
  
  
  Connecting Baserow and creating queries
&lt;/h2&gt;

&lt;p&gt;Let's start by connecting Baserow to ToolJet.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;Datasource manager&lt;/strong&gt; on the left sidebar and click on the &lt;strong&gt;+&lt;/strong&gt; button to add a datasource.&lt;/li&gt;
&lt;li&gt;Select Baserow from the modal that pops up.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-22-at-8.20.52-AM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;Enter the &lt;strong&gt;Baserow API key&lt;/strong&gt; and select whether it's &lt;strong&gt;Baserow Cloud or Self-Host&lt;/strong&gt;.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F09%2FScreenshot-2022-09-22-at-8.21.21-AM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;Let's go to the Baserow dashboard and get the API key. You can create a new &lt;strong&gt;API key&lt;/strong&gt; from the &lt;strong&gt;Personal API tokens&lt;/strong&gt; in &lt;strong&gt;Settings&lt;/strong&gt; of the Baserow
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-20-at-4.53.12-PM-1.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;Copy-paste the API key on ToolJet, and click on the &lt;strong&gt;Save&lt;/strong&gt; button to save the datasource.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's create the &lt;strong&gt;queries&lt;/strong&gt; and connect them to components. For this application, we need to create 4 queries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;issues&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;team&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;files&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;triage&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  issues
&lt;/h3&gt;

&lt;p&gt;This query will get the list of all the rows from the issues table in the baserow. We will also write some JS code in &lt;strong&gt;transformation&lt;/strong&gt; to transform our returned data from the query.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;Query Panel&lt;/strong&gt;, and click on the &lt;strong&gt;+&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;Create a new &lt;strong&gt;Baserow&lt;/strong&gt; query and select the &lt;strong&gt;List rows&lt;/strong&gt; operation from the &lt;strong&gt;operations&lt;/strong&gt; dropdown and in the Table ID field enter the ID of the table in database.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-22-at-8.16.17-AM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;To get the Table ID, you can go to the Baserow dashboard, click on the three dots next to the &lt;strong&gt;database name&lt;/strong&gt; and select the &lt;strong&gt;View API docs&lt;/strong&gt; option. It will open up the &lt;strong&gt;documentation&lt;/strong&gt; specific to that particular database that will have IDs and all the related information for that database.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-22-at-8.37.36-AM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;After entering the Table ID, enable the &lt;strong&gt;Transformations&lt;/strong&gt; and write the JS code to add a new object in the returned data. The following JS code will add a new array &lt;strong&gt;chartData&lt;/strong&gt; to the returned data from the query. The chartData will include objects that will have the total count for Assigned, In progress, and closed issues in the database.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chartData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Assigned&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;In progress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Closed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;

&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Assigned&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;chartData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;In progress&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;chartData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;chartData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;chartData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;chartData&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab and enable the &lt;code&gt;Run query on page load?&lt;/code&gt; so that the query runs every time the app is loaded.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Save &amp;amp; Run&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Now, you'll be able to see the updated data on the table and on the chart.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  team
&lt;/h3&gt;

&lt;p&gt;This query will list all the rows from the &lt;strong&gt;team&lt;/strong&gt; table in the database.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new &lt;strong&gt;Baserow&lt;/strong&gt; query, select &lt;strong&gt;List rows&lt;/strong&gt; from the &lt;strong&gt;operations&lt;/strong&gt; dropdown, and enter the &lt;strong&gt;Table ID&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab and enable the &lt;strong&gt;Run query on page load?&lt;/strong&gt; so that the query runs every time the app is loaded.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Save &amp;amp; Run&lt;/strong&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-22-at-8.48.12-AM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  files
&lt;/h3&gt;

&lt;p&gt;This query will list all the rows from the files table in the database.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new &lt;strong&gt;Baserow&lt;/strong&gt; query, select &lt;strong&gt;List rows&lt;/strong&gt; from the &lt;strong&gt;operations&lt;/strong&gt; dropdown, and enter the &lt;strong&gt;Table ID&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab and enable the &lt;strong&gt;Run query on page load?&lt;/strong&gt; so that the query runs every time the app is loaded.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Save &amp;amp; Run&lt;/strong&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-22-at-8.48.26-AM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  triage
&lt;/h3&gt;

&lt;p&gt;This query will &lt;strong&gt;update&lt;/strong&gt; the &lt;strong&gt;status&lt;/strong&gt; of an issue in the &lt;strong&gt;issues&lt;/strong&gt; table.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new &lt;strong&gt;Baserow&lt;/strong&gt; query, select the &lt;strong&gt;Update row&lt;/strong&gt; from the operations dropdown, and enter the &lt;strong&gt;Table ID&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Row ID&lt;/strong&gt; field, we will get the value from the selected row in the table using the dynamic variable &lt;code&gt;{{components.table1.selectedRow.id}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Record&lt;/strong&gt; field, we will get the value from the &lt;strong&gt;dropdown&lt;/strong&gt; that we have added in the Review &amp;amp; Triage tab:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dropdown1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab and add an event handler to run the &lt;strong&gt;issues&lt;/strong&gt; query every time the query is successful, so that whenever the status is updated the table gets reloaded on the ToolJet.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Save &amp;amp; Run&lt;/strong&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-22-at-8.48.37-AM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;li&gt;Now go to the &lt;strong&gt;Update button&lt;/strong&gt; on &lt;strong&gt;Review &amp;amp; triage&lt;/strong&gt; tab and add an &lt;strong&gt;event handler&lt;/strong&gt; to run the &lt;strong&gt;triage&lt;/strong&gt; query.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-22-at-8.58.26-AM.png" alt="tooljet" width="800" height="400"&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Releasing your application
&lt;/h2&gt;

&lt;p&gt;Click on the &lt;strong&gt;Release&lt;/strong&gt; button at the top right corner of the app builder and the version which is currently opened will be released.&lt;/p&gt;

&lt;p&gt;You can click on the &lt;strong&gt;Share&lt;/strong&gt; button and enable the make application public allowing anyone to use the application without signing it. You can also customize the shareable URL of your application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-22-at-8.32.20-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2FScreenshot-2022-09-22-at-8.32.20-AM.png" alt="tooljet" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Voila!! You have successfully created an internal &lt;strong&gt;Ticket Triaging Application&lt;/strong&gt; using almost no code 🎉&lt;/p&gt;

&lt;p&gt;If you have any queries related to building applications with ToolJet or just want to hang out in the community of low-code application developers just drop us a Hi in our &lt;a href="https://tooljet.com/slack" rel="noopener noreferrer"&gt;Slack Community&lt;/a&gt;. 🚀&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Building a MinIO file explorer app in 30 minutes</title>
      <dc:creator>Shubhendra Singh Chauhan</dc:creator>
      <pubDate>Fri, 02 Sep 2022 08:31:14 +0000</pubDate>
      <link>https://forem.com/tooljet/building-a-minio-file-explorer-app-in-30-minutes-4obf</link>
      <guid>https://forem.com/tooljet/building-a-minio-file-explorer-app-in-30-minutes-4obf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In this tutorial, we will build an internal tool for reading, downloading and uploading objects to the buckets in MinIO.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is MinIO?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.minio.io/" rel="noopener noreferrer"&gt;Minio&lt;/a&gt; is an open-source distributed object storage server designed for Private Cloud infrastructure providing S3 storage functionality. Minio is can be used for storing unstructured data such as photos, videos, log files, backups, and containers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you'll need to build the GCS file explorer?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ToolJet&lt;/strong&gt; (&lt;a href="https://github.com/ToolJet/ToolJet" rel="noopener noreferrer"&gt;https://github.com/ToolJet/ToolJet&lt;/a&gt;): A free and open-source low-code platform that allows you to quickly build applications. You can create a free account on &lt;a href="https://www.tooljet.com/" rel="noopener noreferrer"&gt;ToolJet Cloud&lt;/a&gt; or run it on your &lt;a href="https://docs.tooljet.com/docs/setup/" rel="noopener noreferrer"&gt;local machine&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MinIO&lt;/strong&gt;: Check out the various editions and their &lt;a href="https://min.io/pricing" rel="noopener noreferrer"&gt;Pricing&lt;/a&gt; here. I have used the community edition using docker for this tutorial.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Bonus&lt;/strong&gt;: &lt;a href="https://blog.tooljet.com/content/files/2022/08/file_explorer_minio-export-1661898635143.json" rel="noopener noreferrer"&gt;Download the exported application&lt;/a&gt; and import it to your ToolJet account to use it right away. &lt;/p&gt;

&lt;p&gt;Here's a glimpse of the application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F08%2Fminiodemo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F08%2Fminiodemo.gif" alt="gir" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Without further ado, let's start building the application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building the UI of the explorer
&lt;/h2&gt;

&lt;p&gt;Let's start with building the UI for Explorer. Login to ToolJet and then on the &lt;strong&gt;Dashboard&lt;/strong&gt;, click on the &lt;strong&gt;Create new application&lt;/strong&gt; button to create a new app. Once the app is created, you will be redirected to the visual app editor. You can change the name of the app by editing the default name i.e &lt;strong&gt;Untitled app&lt;/strong&gt; from the top left of the app builder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2021%2F12%2Flogin-1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2021%2F12%2Flogin-1.gif" alt="gif" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The visual app editor has 4 sections:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Canvas&lt;/strong&gt; is at the center, where you'll drag and drop widgets to build UI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://docs.tooljet.com/docs/tutorial/building-queries" rel="noopener noreferrer"&gt;Query editor&lt;/a&gt;&lt;/strong&gt; at the bottom, where you can create queries.&lt;/li&gt;
&lt;li&gt;On the right sidebar, you'll find &lt;strong&gt;&lt;a href="https://docs.tooljet.com/docs/tutorial/adding-widget/" rel="noopener noreferrer"&gt;Widget Manager&lt;/a&gt;&lt;/strong&gt; which has a list of built-in widgets and components. You can drag and drop to start building out the user interface.&lt;/li&gt;
&lt;li&gt;On the left sidebar, you'll see the Inspector, debugger, comments, settings, and &lt;strong&gt;&lt;a href="https://docs.tooljet.com/docs/tutorial/adding-a-datasource" rel="noopener noreferrer"&gt;Datasource manager&lt;/a&gt;&lt;/strong&gt;. The datasource manager is used to add a new datasource or manage the connected datasource.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Let's build the UI
&lt;/h3&gt;

&lt;p&gt;For building the user interface, you’ll need to drag and drop the following components from the Widget Manager(right sidebar) and place them accordingly.&lt;/p&gt;

&lt;p&gt;Here is the configuration of widgets that I used for building the UI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;Container&lt;/strong&gt; as header and &lt;strong&gt;Text widget&lt;/strong&gt; inside the container to give a title to the app i.e &lt;strong&gt;MinIO File Explorer&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--1-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--1-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Another &lt;strong&gt;container&lt;/strong&gt; below the header will contain all the sections of the application. Give this container a background color of your choice from the Styles.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--2-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--2-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's add a &lt;strong&gt;text&lt;/strong&gt; widget in the center and set the text to &lt;code&gt;Please select a bucket&lt;/code&gt; - we will display this text by conditionally disabling the visibility of the container that we will add on top of this text widget&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--3-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--3-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's drag a &lt;strong&gt;container&lt;/strong&gt; on top of the text widget, and put list view widget inside the container. You can also use &lt;strong&gt;text&lt;/strong&gt; widgets to set columns names- Name, Last updated, Size, and Actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--4-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--4-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the &lt;strong&gt;List view&lt;/strong&gt; widget, use text widget for name, updated on, and size. Use Image widget for the Action. User will click on the &lt;strong&gt;download&lt;/strong&gt; image to download the object from the MinIO.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--5-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--5-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set the following field value for the three text widgets Name, Updated on, and Size as &lt;code&gt;{{listItem.name}}&lt;/code&gt;, &lt;code&gt;{{moment(listItem.lastModified).format("DD/MM/YYYY h:mm:ss a")}}&lt;/code&gt;, and &lt;code&gt;{{(listItem.size/1024).toFixed(2)}}&lt;/code&gt; kb respectively. In the image widget set the loading state value to &lt;code&gt;{{listItem.id === variables.currentlyLoadingId}}&lt;/code&gt; , and add the event handler to open the webpage &lt;code&gt;{{queries.urlfordownload.data.url}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--6-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--6-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Drag a &lt;strong&gt;button&lt;/strong&gt; on the right side of the container that will be used to trigger the dialog for &lt;strong&gt;choosing the bucket&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--7-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--7-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Drag a &lt;strong&gt;modal&lt;/strong&gt; somewhere below the container, go to the button properties and set the &lt;strong&gt;event handler&lt;/strong&gt; to &lt;strong&gt;show the modal&lt;/strong&gt; that you have added.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--8-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--8-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the button to show the modal, and then you can drag and drop &lt;strong&gt;dropdown&lt;/strong&gt; and &lt;strong&gt;button&lt;/strong&gt; widget inside the modal to build the modal UI. The dropdown will include the list of buckets that we will retrieve from the query, and the button will have an event handler to fire the query for listing the files from the selected bucket.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--9-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--9-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's add text widget next to button for showing up the currently selected bucket. Set the &lt;strong&gt;text&lt;/strong&gt; value as &lt;code&gt;{{components.dropdown1.value}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--10-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--10-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, the last section of the UI - the &lt;strong&gt;upload&lt;/strong&gt; section. We will build this section inside a container. We will be using &lt;strong&gt;text, divider, text input, file picker and button&lt;/strong&gt; widget to build the section. The button widget will include an event handler for firing up the &lt;strong&gt;upload&lt;/strong&gt; query that we will create later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--11-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--11-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Check the documentation to learn more about customizing the widgets and beautifying the UI. ✨&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, we are done building the UI - let's move forward with connecting the MinIO and build the queries.&lt;/p&gt;




&lt;h2&gt;
  
  
  Connecting the MinIO datasource and creating queries
&lt;/h2&gt;

&lt;p&gt;Before creating the queries let's connect the MinIO datasource first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the datasource manager on the left sidebar and click on + button to &lt;strong&gt;add a new datasource&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Search and click on &lt;strong&gt;MinIO&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enter the &lt;strong&gt;Host, Port, Username and Password&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You can click on &lt;code&gt;Test connection&lt;/code&gt; button to check the connection and then click on &lt;strong&gt;Save&lt;/strong&gt; button to save the datasource.&lt;/li&gt;
&lt;li&gt;Now, we are good to go for creating queries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--12-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--12-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;For this application, we will need to build the queries for:&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript code for triggering show modal action&lt;/li&gt;
&lt;li&gt;Listing the buckets from MinIO&lt;/li&gt;
&lt;li&gt;Listing the object/files from the selected bucket&lt;/li&gt;
&lt;li&gt;Uploading the file to the selected bucket&lt;/li&gt;
&lt;li&gt;Creating signed URL for downloading the object from the bucket&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  JavaScript code for triggering show modal action
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to the Query Panel, and click on the &lt;code&gt;+&lt;/code&gt; button&lt;/li&gt;
&lt;li&gt;Create a new &lt;code&gt;JavaScript code query&lt;/code&gt; and enter the following code for triggering the show modal action:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showModal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;modal1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--13-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--13-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab, toggle on the &lt;strong&gt;Run query on page load?&lt;/strong&gt; option, and save the query as &lt;strong&gt;showModalOnPageLoad&lt;/strong&gt;. Enabling the Run query on page load option will display the modal every time the app is loaded - giving users the flexibility to choose the bucket before moving to other app functions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Listing the buckets from MinIO
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to the Query Panel, and click on the &lt;strong&gt;+&lt;/strong&gt; button to create a new query&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;MinIO&lt;/strong&gt; as the datasource&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;operations&lt;/strong&gt; dropdown, select the &lt;strong&gt;List buckets&lt;/strong&gt; option&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--14-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--14-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab, toggle on the &lt;strong&gt;Run query on page load?&lt;/strong&gt; option, and click &lt;strong&gt;Save and Run&lt;/strong&gt; button.&lt;/li&gt;
&lt;li&gt;Let's open up the modal by clicking on the &lt;strong&gt;change&lt;/strong&gt; button, and then edit the properties of the dropdown inside the modal. Set the &lt;strong&gt;Option Values&lt;/strong&gt; and &lt;strong&gt;Option Label&lt;/strong&gt; as &lt;code&gt;{{queries.listBuckets.data.map(row =&amp;gt; row.name)}}&lt;/code&gt; , the Default value to &lt;code&gt;{{queries.listBuckets.data.map(row =&amp;gt; row.name)[0]}}&lt;/code&gt;, and &lt;strong&gt;Options loading state&lt;/strong&gt; to &lt;code&gt;{{queries.listBuckets.isLoading}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--15-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--15-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Listing the object/files from the selected bucket
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;Query Panel&lt;/strong&gt;, and click on the &lt;strong&gt;+&lt;/strong&gt; button to create a new query&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;MinIO&lt;/strong&gt; as the &lt;strong&gt;datasource&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;operations&lt;/strong&gt; dropdown, select the &lt;strong&gt;List objects in a bucket&lt;/strong&gt; option&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Bucket&lt;/strong&gt; field, use JS to dynamically get the value from the selected option in the dropdown widget - &lt;code&gt;{{components.dropdown1.value}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--16-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--16-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab and add an &lt;strong&gt;event handler&lt;/strong&gt; to &lt;strong&gt;close the modal&lt;/strong&gt; once the &lt;strong&gt;query is successful&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Save and run&lt;/strong&gt; the query as &lt;strong&gt;listFiles&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--17-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--17-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's open up the &lt;strong&gt;modal&lt;/strong&gt; by clicking on the &lt;strong&gt;change&lt;/strong&gt; button, and then edit the properties of the button that is inside the modal. Add an &lt;strong&gt;event handler&lt;/strong&gt; for running the &lt;strong&gt;listFiles&lt;/strong&gt; query for &lt;strong&gt;On Click&lt;/strong&gt; event.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--18-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--18-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;list view&lt;/strong&gt; widget and connect the data returned by the query. Set list data field value to &lt;code&gt;{{queries.listFiles.data.files}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Uploading the file to the selected bucket
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to the Query Panel, and click on the &lt;strong&gt;+&lt;/strong&gt; button to create a new query&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;MinIO&lt;/strong&gt; as the &lt;strong&gt;datasource&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;operations&lt;/strong&gt; dropdown, select the &lt;strong&gt;Put object&lt;/strong&gt; option&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Bucket&lt;/strong&gt; field enter &lt;code&gt;{{components.dropdown1.value}}&lt;/code&gt; , &lt;strong&gt;File name&lt;/strong&gt; field enter &lt;code&gt;{{components.textinput1.value}}&lt;/code&gt; , &lt;strong&gt;Content type&lt;/strong&gt; field enter &lt;code&gt;{{components.filepicker1.file[0].type}}&lt;/code&gt; , and &lt;strong&gt;Upload data&lt;/strong&gt; field enter &lt;code&gt;{{components.filepicker1.file[0].content}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--19-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--19-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab and add the two event handlers, one to run the &lt;strong&gt;listFiles&lt;/strong&gt; query for the On Success event. This will reload the list of files in the listview widget.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--20-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--20-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;And the other event handler to set &lt;strong&gt;component specific action&lt;/strong&gt; for file picker that will clear the file from the widget once the query is successful.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--21-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--21-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Save and run&lt;/strong&gt; the query as upload.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Creating signed URL for downloading the file from the bucket
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go to the Query Panel, and click on the &lt;strong&gt;+&lt;/strong&gt; button to create a new query&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;MinIO&lt;/strong&gt; as the &lt;strong&gt;datasource&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;operations&lt;/strong&gt; dropdown, select the &lt;strong&gt;Presigned URL for download&lt;/strong&gt; option&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Bucket&lt;/strong&gt; field enter &lt;code&gt;{{components.dropdown1.value}}&lt;/code&gt;, and in &lt;strong&gt;File name&lt;/strong&gt; field enter &lt;code&gt;{{queries.listFiles.data.Body[components.listview2.selectedRowId].name}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--22-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--22-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab and set an &lt;strong&gt;event handler&lt;/strong&gt; to &lt;code&gt;unset a variable&lt;/code&gt; - &lt;strong&gt;currentlyLoadingId&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--23-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F09%2Foutput-onlinepngtools--23-.png" alt="cont" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save the query as &lt;strong&gt;urlfordownload&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Go to the &lt;strong&gt;list view&lt;/strong&gt; widget and click on its handle to &lt;strong&gt;edit its properties&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add the &lt;strong&gt;two event handlers&lt;/strong&gt;- one to &lt;strong&gt;set a variable&lt;/strong&gt; &lt;code&gt;currentlyLoadingId&lt;/code&gt; for &lt;strong&gt;On row click&lt;/strong&gt; event and set its value to &lt;code&gt;{{queries.listFiles.data.Body[components.listview2.selectedRowId].name}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;And the other &lt;strong&gt;handler&lt;/strong&gt; to run the &lt;strong&gt;urlfordownload&lt;/strong&gt; query.&lt;/li&gt;
&lt;li&gt;Now you can click on one of the row on the list view widget and it will fire up the urlfordownload query.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Awesome! We have successfully built all the queries and connected with the UI.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;And now FINALLY just &lt;strong&gt;Release&lt;/strong&gt; your application from the top right corner of the app editor.&lt;/p&gt;

&lt;p&gt;You have successfully created a &lt;strong&gt;File explorer app for your MinIO object storage&lt;/strong&gt; 🎉&lt;/p&gt;




&lt;p&gt;If you have any queries related to building applications with ToolJet or just want to hang out in the community of low-code application developers just drop us a Hi in our &lt;a href="https://join.slack.com/t/tooljet/shared_invite/zt-r2neyfcw-KD1COL6t2kgVTlTtAV5rtg" rel="noopener noreferrer"&gt;Slack Community&lt;/a&gt;. 🚀&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Building a Google Cloud Storage (GCS) file explorer app in 30 minutes</title>
      <dc:creator>Shubhendra Singh Chauhan</dc:creator>
      <pubDate>Mon, 22 Aug 2022 12:44:37 +0000</pubDate>
      <link>https://forem.com/tooljet/building-a-google-cloud-storage-gcs-file-explorer-app-in-30-minutes-4ck4</link>
      <guid>https://forem.com/tooljet/building-a-google-cloud-storage-gcs-file-explorer-app-in-30-minutes-4ck4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In this tutorial, we will build an internal tool for reading, downloading and uploading files to the buckets in Google Cloud Storage.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  What is Google Cloud Storage?
&lt;/h4&gt;

&lt;p&gt;Google Cloud Storage (GCS) is the global, secure, and scalable object storage for immutable data such as images, texts, videos, or any other file format. Objects are stored in buckets that are associated with a project, which are grouped under an organization.&lt;/p&gt;

&lt;h4&gt;
  
  
  What you'll need to build the GCS file explorer?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ToolJet&lt;/strong&gt; (&lt;a href="https://github.com/ToolJet/ToolJet):" rel="noopener noreferrer"&gt;https://github.com/ToolJet/ToolJet):&lt;/a&gt; A free and open-source low-code platform that allows you to quickly build applications. You can create a free account on &lt;a href="https://www.tooljet.com/" rel="noopener noreferrer"&gt;ToolJet Cloud&lt;/a&gt; or run it on your &lt;a href="https://docs.tooljet.com/docs/setup/" rel="noopener noreferrer"&gt;local machine&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Cloud Storage (GCS)&lt;/strong&gt;: JSON private key for the service account required for connecting ToolJet to GCS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Bonus&lt;/strong&gt;: &lt;a href="https://blog.tooljet.com/content/files/2022/08/file_explorer_gcs-export.json" rel="noopener noreferrer"&gt;Download&lt;/a&gt; the exported application from here and import it to your ToolJet account to use it straight away.&lt;/p&gt;

&lt;p&gt;Here's a glimpse of the application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjzrp7xey1583l0itgaue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjzrp7xey1583l0itgaue.png" alt="app" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Without further ado, let's start building the application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building the UI of GCS file explorer
&lt;/h2&gt;

&lt;p&gt;Let's start with building the UI for Explorer. Login to the ToolJet and then on the &lt;strong&gt;Dashboard&lt;/strong&gt;, click on the &lt;strong&gt;Create new application&lt;/strong&gt; button to create a new app. Once the app is created, you will be redirected to the visual app editor. You can change the name of the app by editing the default name i.e &lt;strong&gt;Untitled app&lt;/strong&gt; from the top left of the app builder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2021%2F12%2Flogin-1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2021%2F12%2Flogin-1.gif" alt="new_app" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visual app editor has 4 sections:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Canvas&lt;/strong&gt; at the center, where you'll drag and drop widgets to build UI.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.tooljet.com/docs/tutorial/building-queries" rel="noopener noreferrer"&gt;Query editor&lt;/a&gt; at the bottom, where you can create queries.&lt;/li&gt;
&lt;li&gt;On the right sidebar, you'll find &lt;a href="https://docs.tooljet.com/docs/tutorial/adding-widget/" rel="noopener noreferrer"&gt;Widget Manager&lt;/a&gt; that has a list of built-in widgets and components. You can drag and drop to start building out user interface.&lt;/li&gt;
&lt;li&gt;On the left sidebar, you'll see the Inspector, debugger, comments, settings, and &lt;a href="https://docs.tooljet.com/docs/tutorial/adding-a-datasource" rel="noopener noreferrer"&gt;Datasource manager&lt;/a&gt;. Datasource manager is used to add a new datasource or manage the connected datasource.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Let's build the UI
&lt;/h3&gt;

&lt;p&gt;For building the user interface, you’ll need to drag and drop the following components from the Widget Manager(right sidebar) and place them accordingly.&lt;/p&gt;

&lt;p&gt;Here is the configuration of widgets that I used for building the UI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;Container&lt;/strong&gt; as header and &lt;strong&gt;Text&lt;/strong&gt; widget inside the container to give a title to the app i.e &lt;strong&gt;GCS File Explorer&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-1.41.51-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-1.41.51-AM.png" alt="header" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Another &lt;strong&gt;container&lt;/strong&gt; below the header that will contain all the sections of the application. Give this container a background color of your choice from the Styles.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-1.44.45-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-1.44.45-AM.png" alt="container" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's add a &lt;strong&gt;text&lt;/strong&gt; widget in the center and set the text to &lt;strong&gt;Please select a bucket&lt;/strong&gt; - we will display this text by conditionally disabling the visibility of the container that we will add on top of this text widget.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-1.50.29-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-1.50.29-AM.png" alt="select" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's drag a &lt;strong&gt;container&lt;/strong&gt; on top of the text widget, and put list view widget inside the container. You can also use &lt;strong&gt;text&lt;/strong&gt; widgets to set columns names- &lt;strong&gt;Name, Updated on, Size, and Actions.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-1.52.35-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-1.52.35-AM.png" alt="drag" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the &lt;strong&gt;List view&lt;/strong&gt; widget, use text widget for name, updated on, and size. Use Image widget for the Action. User will click on the &lt;strong&gt;download&lt;/strong&gt; image to download the object from the GCS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-1.57.29-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-1.57.29-AM.png" alt="list" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set the following field value for the three text widgets &lt;strong&gt;Name, Updated on, and Size&lt;/strong&gt; as &lt;code&gt;{{listItem.name}}&lt;/code&gt;, &lt;code&gt;{{moment(listItem).format("DD/MM/YYYY h:mm:ss a")}}&lt;/code&gt;, and &lt;code&gt;{{(listItem.size/1024).toFixed(2)}}&lt;/code&gt; kb respectively. In the image widget set the loading state value to &lt;code&gt;{{listItem.id === variables.currentlyLoadingId}}&lt;/code&gt; , and add the event handler to open the webpage &lt;code&gt;{{queries.urlfordownload.data.url}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.43.05-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.43.05-AM.png" alt="event" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Drag a &lt;strong&gt;button&lt;/strong&gt; on the right side of the container that will be used to trigger the dialog for &lt;strong&gt;choosing the bucket&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.00.44-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.00.44-AM.png" alt="button" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Drag a &lt;strong&gt;modal&lt;/strong&gt; somewhere below the container, go to the button properties and set the &lt;strong&gt;event handler&lt;/strong&gt; to &lt;strong&gt;show the modal&lt;/strong&gt; that you have added.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.03.18-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.03.18-AM.png" alt="modal" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the button to show the modal, and then you can drag and drop &lt;strong&gt;dropdown&lt;/strong&gt; and &lt;strong&gt;button&lt;/strong&gt; widget inside the modal to build the modal UI. The dropdown will include the list of buckets that we will retrieve from the query, and the button will have an event handler to fire the query for listing the files from the selected bucket.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.05.58-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.05.58-AM.png" alt="dropdown" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's add &lt;strong&gt;text&lt;/strong&gt; widget next to button for showing up the currently selected bucket. Set the text value as &lt;code&gt;{{components.dropdown1.value}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.17.02-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.17.02-AM.png" alt="text" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, the last section of the UI - the &lt;strong&gt;upload&lt;/strong&gt; section. We will build this section inside a container. We will be using &lt;strong&gt;text, divider, text input, file picker and button&lt;/strong&gt; widget to build the section. The button widget will include an event handler for firing up the &lt;strong&gt;upload&lt;/strong&gt; query that we will create later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.20.11-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.20.11-AM.png" alt="upload" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Check the &lt;a href="https://docs.tooljet.com/docs/widgets/text" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; to learn more about customising the widgets and beautifying the UI. ✨&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, we are done building the UI - let's move forward with connecting the Google Cloud Storage and build the queries.&lt;/p&gt;




&lt;h2&gt;
  
  
  Connecting the GCS datasource and creating queries
&lt;/h2&gt;

&lt;p&gt;Before creating the queries let's connect the GCS datasource first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the datasource manager on the left sidebar and click on &lt;strong&gt;+&lt;/strong&gt; button to &lt;strong&gt;add a new datasource&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Search and click on &lt;strong&gt;Google Cloud Storage&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enter and save the &lt;strong&gt;JSON private key for the service account&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You can click on &lt;strong&gt;Test connection&lt;/strong&gt; button to check the connection and then click on &lt;strong&gt;Save&lt;/strong&gt; button to save the datasource.&lt;/li&gt;
&lt;li&gt;Now, we are good to go for creating queries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.26.47-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.26.47-AM.png" alt="save" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  For this application, we will need to build the queries for:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript code for triggering show modal action&lt;/li&gt;
&lt;li&gt;Listing the buckets from GCS&lt;/li&gt;
&lt;li&gt;Listing the object/files from the selected bucket&lt;/li&gt;
&lt;li&gt;Uploading the file to the selected bucket&lt;/li&gt;
&lt;li&gt;Creating signed URL for downloading the file from the bucket&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  JavaScript code for triggering show modal action
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Go to the Query Panel, and click on the &lt;strong&gt;+&lt;/strong&gt; button
Create a new &lt;strong&gt;JavaScript code&lt;/strong&gt; query and enter the following code for triggering the show modal action:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showModal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;modal1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.32.52-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.32.52-AM.png" alt="js" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab, toggle on the Run query on page load? option, and save the query as &lt;strong&gt;showModalOnPageLoad&lt;/strong&gt;. Enabling Run query on page load option will display the modal every time the app is loaded - giving users the flexibility to choose the bucket before moving to other app functions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Listing the buckets from GCS
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Go to the Query Panel, and click on the &lt;strong&gt;+&lt;/strong&gt; button to create a new query&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Google Cloud Storage&lt;/strong&gt; as the datasource&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;operations&lt;/strong&gt; dropdown, select the &lt;strong&gt;List buckets&lt;/strong&gt; option&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.56.08-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-2.56.08-AM.png" alt="listbuckets" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab, toggle on the &lt;strong&gt;Run query on page load?&lt;/strong&gt; option, and click &lt;strong&gt;Save and Run&lt;/strong&gt; button.&lt;/li&gt;
&lt;li&gt;Let's open up the &lt;strong&gt;modal&lt;/strong&gt; by clicking on the &lt;strong&gt;change&lt;/strong&gt; button, and then edit the properties of the &lt;strong&gt;dropdown&lt;/strong&gt; inside the &lt;strong&gt;modal&lt;/strong&gt;. Set the Option Values and Option Label as &lt;code&gt;{{queries.listBuckets.data.buckets}}&lt;/code&gt; , Default value to &lt;code&gt;{{queries.listBuckets.data.buckets[0]}}&lt;/code&gt;, and Options loading state to &lt;code&gt;{{queries.listBuckets.isLoading}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.09.32-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.09.32-AM.png" alt="option" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Listing the object/files from the selected bucket
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Go to the Query Panel, and click on the &lt;strong&gt;+&lt;/strong&gt; button to create a new query&lt;/li&gt;
&lt;li&gt;Select Google Cloud Storage as the datasource&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;operations&lt;/strong&gt; dropdown, select the &lt;strong&gt;List files in a bucket&lt;/strong&gt; option&lt;/li&gt;
&lt;li&gt;In &lt;strong&gt;Bucket&lt;/strong&gt; field, use JS to dynamically get the value from the selected option in the dropdown widget - &lt;code&gt;{{components.dropdown1.value}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.12.45-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.12.45-AM.png" alt="listfiles" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, go to &lt;strong&gt;Advanced&lt;/strong&gt; tab and add an event handler to &lt;strong&gt;close the modal&lt;/strong&gt; once the query is successful.&lt;/li&gt;
&lt;li&gt;Save and run the query as &lt;strong&gt;listFiles&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.14.42-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.14.42-AM.png" alt="save" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's open up the &lt;strong&gt;modal&lt;/strong&gt; by clicking on the &lt;strong&gt;change&lt;/strong&gt; button, and then edit the properties of the button that is inside the modal. Add an &lt;strong&gt;event handler&lt;/strong&gt; for running the &lt;strong&gt;listFiles&lt;/strong&gt; query for &lt;strong&gt;On Click&lt;/strong&gt; event.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.18.04-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.18.04-AM.png" alt="onclick" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;list view&lt;/strong&gt; widget and connect the data returned by the query. Set list data field value to &lt;code&gt;{{queries.listFiles.data.files}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Uploading the file to the selected bucket
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;Query Panel&lt;/strong&gt;, and click on the &lt;strong&gt;+&lt;/strong&gt; button to create a new query&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Google Cloud Storage&lt;/strong&gt; as the datasource&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;operations&lt;/strong&gt; dropdown, select the &lt;strong&gt;Upload file&lt;/strong&gt; option&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Bucket&lt;/strong&gt; field enter &lt;code&gt;{{components.dropdown1.value}}&lt;/code&gt; , &lt;strong&gt;File name&lt;/strong&gt; field enter &lt;code&gt;{{components.textinput1.value}}&lt;/code&gt; , &lt;strong&gt;Content&lt;/strong&gt; type field enter &lt;code&gt;{{components.filepicker1.file[0].type}}&lt;/code&gt; , &lt;strong&gt;Upload data&lt;/strong&gt; field enter &lt;code&gt;{{components.filepicker1.file[0].content}}&lt;/code&gt; , and set &lt;strong&gt;Encoding&lt;/strong&gt; to &lt;strong&gt;utf8&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.21.13-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.21.13-AM.png" alt="encoding" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;strong&gt;Advanced&lt;/strong&gt; tab and add the &lt;strong&gt;two event handlers&lt;/strong&gt;, one to run the &lt;strong&gt;listFiles&lt;/strong&gt; query for &lt;strong&gt;On Success&lt;/strong&gt; event. This will reload the list of files in the listview widget.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.21.51-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.21.51-AM.png" alt="query1" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;And the other &lt;strong&gt;event handler&lt;/strong&gt; to &lt;strong&gt;set component specific action&lt;/strong&gt; for &lt;strong&gt;file picker&lt;/strong&gt; that will &lt;strong&gt;clear the file&lt;/strong&gt; from the widget once the query is successful.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.22.00-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.22.00-AM.png" alt="claer" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Save and run&lt;/strong&gt; the query as &lt;strong&gt;upload&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Creating signed URL for downloading the file from the bucket
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;Query Panel&lt;/strong&gt;, and click on the &lt;strong&gt;+&lt;/strong&gt; button to create a new query&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Google Cloud Storage&lt;/strong&gt; as the datasource&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;operations&lt;/strong&gt; dropdown, select the &lt;strong&gt;Signed URL for download&lt;/strong&gt; option&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Bucket&lt;/strong&gt; field enter &lt;code&gt;{{components.dropdown1.value}}&lt;/code&gt;, and in &lt;strong&gt;File name&lt;/strong&gt; field enter &lt;code&gt;{{queries.listFiles.data.files[components.listview2.selectedRowId].name}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.46.26-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.46.26-AM.png" alt="file" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab and set an event handler to &lt;strong&gt;unset a variable&lt;/strong&gt; - &lt;strong&gt;currentlyLoadingId&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.46.51-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F08%2FScreenshot-2022-08-22-at-3.46.51-AM.png" alt="set" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save the query as &lt;strong&gt;urlfordownload&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Go to the &lt;strong&gt;list view&lt;/strong&gt; widget and click on its handle to edit its properties.&lt;/li&gt;
&lt;li&gt;Add the two event handlers- one to &lt;strong&gt;set a variable&lt;/strong&gt; &lt;strong&gt;currentlyLoadingId&lt;/strong&gt; for On row click event and set its value to &lt;code&gt;{{queries.listFiles.data.files[components.listview2.selectedRowId].id}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;And the other handler to run the &lt;strong&gt;urlfordownload&lt;/strong&gt; query.&lt;/li&gt;
&lt;li&gt;Now you can click one on row on the list view widget and it will fire up the &lt;strong&gt;urlfordownload&lt;/strong&gt; query.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Awesome! We have successfully built all the queries and connected with the UI.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;And now FINALLY just &lt;strong&gt;Release&lt;/strong&gt; your application from the top right corner of the app editor.&lt;/p&gt;

&lt;p&gt;You have successfully created a &lt;strong&gt;File explorer app for your Google Cloud Storage&lt;/strong&gt;. 🎉&lt;/p&gt;




&lt;p&gt;If you have any queries related to building applications with ToolJet or just want to hangout in the community of low-code application developers the just drop us a Hi in our &lt;a href="https://join.slack.com/t/tooljet/shared_invite/zt-r2neyfcw-KD1COL6t2kgVTlTtAV5rtg" rel="noopener noreferrer"&gt;Slack Community&lt;/a&gt;. 🚀&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Build HR Management System using MongoDB and ToolJet (Part 4: Leave Requests)</title>
      <dc:creator>Shubhendra Singh Chauhan</dc:creator>
      <pubDate>Mon, 11 Jul 2022 11:34:17 +0000</pubDate>
      <link>https://forem.com/tooljet/build-hr-management-system-using-mongodb-and-tooljet-part-4-leave-requests-51l4</link>
      <guid>https://forem.com/tooljet/build-hr-management-system-using-mongodb-and-tooljet-part-4-leave-requests-51l4</guid>
      <description>&lt;h2&gt;
  
  
  Request Leaves
&lt;/h2&gt;

&lt;p&gt;This is the last application and this application will act as a dashboard for all the employees for requesting the leaves and getting the stats on their past leaves.&lt;/p&gt;

&lt;p&gt;To build this application, clone the last application that we built, edit the cloned app and remove all the widgets except the header and sidebar. Remove all the queries, rename the application from &lt;code&gt;Employees and Requests&lt;/code&gt; to &lt;code&gt;Request Leaves&lt;/code&gt; , and &lt;strong&gt;Disable&lt;/strong&gt; the &lt;strong&gt;Request leaves&lt;/strong&gt; button on the sidebar and enable others.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-7.40.26-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-7.40.26-AM.png" alt="requests" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Building the UI
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Rename the header text as &amp;lt;h1&amp;gt;🏖️Leave Scheduler&amp;lt;/h1&amp;gt;&lt;/li&gt;
&lt;li&gt;Drag another Text widget and set the text value to &lt;code&gt;Your recent leave requests&lt;/code&gt;:&lt;/li&gt;
&lt;li&gt;Place a &lt;strong&gt;ListView&lt;/strong&gt; widget, a &lt;strong&gt;button&lt;/strong&gt;, a &lt;strong&gt;modal&lt;/strong&gt;, and &lt;strong&gt;two statistics&lt;/strong&gt; widgets as shown in the image below&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-7.45.36-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-7.45.36-AM.png" alt="requests" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Edit the ListView widget, and set the List Data field value to &lt;code&gt;{{queries.listRequests.data[0].leaves}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In list view widget, place the text widgets and set the following values:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leave requested for date&lt;/strong&gt;: &lt;code&gt;{{moment(listItem.start_date).format("DD-MM-YYYY")}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No. of Days&lt;/strong&gt;: &lt;code&gt;{{listItem.leave_days}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status&lt;/strong&gt;: &lt;code&gt;{{listItem.leave_days}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;You can style the text color of Status(approved, rejected, requested) text programmatically. Go to the &lt;strong&gt;Styles&lt;/strong&gt; tab and click on the Fx button next to &lt;strong&gt;Text Color&lt;/strong&gt; and set this value: &lt;code&gt;{{listItem.status === "approved" ? "green" : listItem.status === "rejected" ? "red" : "blue"}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-7.53.12-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-7.53.12-AM.png" alt="requests" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the button widget to edit its properties, go to the handlers and add an event handler to show the modal that we added in the previous step.&lt;/li&gt;
&lt;li&gt;After adding the event handler, click on the button to show the modal. When the modal shows up, you can drag on drop widgets on it to build a form&lt;/li&gt;
&lt;li&gt;For labels use &lt;strong&gt;text&lt;/strong&gt; widgets, &lt;strong&gt;datepicker&lt;/strong&gt; widget for getting input for the start date, and a number input widget for the Number of days field.&lt;/li&gt;
&lt;li&gt;Edit date picker properties, set default date to &lt;code&gt;{{moment().format("YYYY-MM-DD")}}&lt;/code&gt; and date format to &lt;code&gt;YYYY-MM-DD&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;For the Number input widget, you can set the maximum and minimum value according to your preference.&lt;/li&gt;
&lt;li&gt;Add a button for submitting the leave request, it will have two event handlers - one for closing the modal and the other for running the query that will add a request to the database. For now, just add one handler for closing the modal, we will add another once we create the queries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-8.00.10-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-8.00.10-AM.png" alt="requests" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the first Statistics widget, set the &lt;strong&gt;Primary Value Label&lt;/strong&gt; as &lt;code&gt;Leaves Approved&lt;/code&gt; and Primary value to &lt;code&gt;{{queries.approvedCount.data.count}}&lt;/code&gt; , and toggle on the &lt;code&gt;Hide secondary value&lt;/code&gt; as this is not required.&lt;/li&gt;
&lt;li&gt;On the second Statistics widget, set the &lt;strong&gt;Primary Value Label&lt;/strong&gt; as &lt;code&gt;Allocated leaves&lt;/code&gt; , we will hardcode the Primary value to &lt;code&gt;24&lt;/code&gt; , set &lt;strong&gt;Secondary Value Label&lt;/strong&gt; as &lt;code&gt;Leave Balance&lt;/code&gt; and &lt;strong&gt;Secondary Value&lt;/strong&gt; as &lt;code&gt;{{24- queries.approvedCount.data.count}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-8.09.06-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-8.09.06-AM.png" alt="requests" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Build the queries
&lt;/h3&gt;

&lt;h4&gt;
  
  
  listRequests
&lt;/h4&gt;

&lt;p&gt;This query will return all those documents that match with the email of the currently logged-in user in ToolJet.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new MongoDB query, select &lt;code&gt;Find Many&lt;/code&gt; Operation and enter the collection name &lt;code&gt;employees&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the Filter field, enter &lt;code&gt;{email: "{{globals.currentUser.email}}"}&lt;/code&gt; - here we are getting the email of the logged-in user through the &lt;strong&gt;exposed variable&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab, and enable the &lt;code&gt;Run query on page load?&lt;/code&gt; option.&lt;/li&gt;
&lt;li&gt;Hit &lt;strong&gt;Save and Run&lt;/strong&gt; button to save and execute the query - You'll see the updated data on the listview widget.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F07%2FScreenshot-2022-07-08-at-8.14.36-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F07%2FScreenshot-2022-07-08-at-8.14.36-AM.png" alt="requests" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  leaveRequest
&lt;/h4&gt;

&lt;p&gt;This query will update a document and add a new object for leave request in the database.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new MongoDB query, select &lt;code&gt;Update One&lt;/code&gt; &lt;strong&gt;Operation&lt;/strong&gt; and enter the &lt;strong&gt;collection&lt;/strong&gt; name &lt;code&gt;employees&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Filter&lt;/strong&gt; field enter &lt;code&gt;{"email": "{{globals.currentUser.email}}"}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Update&lt;/strong&gt; field enter &lt;code&gt;{$push:{"leaves":{"start_date": "{{moment(components.datepicker1.value).toISOString(true)}}", "leave_days":{{components.numberinput1.value}}, "status": "requested"}}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Hit &lt;strong&gt;Save&lt;/strong&gt; button to save the query. Don't hit Run because it will create an empty object in the database since there is no value in the form yet.&lt;/li&gt;
&lt;li&gt;Now, click on the button to show the modal, select the submit button, and the remaining event handler for running this query.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F07%2FScreenshot-2022-07-08-at-8.14.58-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F07%2FScreenshot-2022-07-08-at-8.14.58-AM.png" alt="requests" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  approvedCount
&lt;/h4&gt;

&lt;p&gt;This query returns the total count of the documents that have status field as approved.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new MongoDB query, select &lt;code&gt;Count&lt;/code&gt; &lt;strong&gt;Operation&lt;/strong&gt; and enter the &lt;strong&gt;collection&lt;/strong&gt; name &lt;code&gt;employees&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Filter&lt;/strong&gt; field enter &lt;code&gt;{"leaves.status": "approved"}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab, and enable the &lt;code&gt;Run query on page load?&lt;/code&gt; option.&lt;/li&gt;
&lt;li&gt;Hit &lt;strong&gt;Save and Run&lt;/strong&gt; button to save and execute the query - You'll see the value on the statistics widget gets updated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F07%2FScreenshot-2022-07-08-at-8.15.08-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F07%2FScreenshot-2022-07-08-at-8.15.08-AM.png" alt="requests" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, You can now release the last application by clicking the &lt;strong&gt;Release&lt;/strong&gt; button on the top right of the app editor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-8.13.05-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-8.13.05-AM.png" alt="requests" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Connecting the applications on the sidebar of each application
&lt;/h2&gt;

&lt;p&gt;Now that we have all 4 applications released - All you need to do is to make the applications &lt;strong&gt;Public&lt;/strong&gt; by clicking on the share button on the navbar of App-editor. After making the application public, create a custom &lt;strong&gt;shareable URL&lt;/strong&gt; for all 4 applications.&lt;/p&gt;

&lt;p&gt;For connecting all 4 applications, you'll need to edit the &lt;strong&gt;buttons&lt;/strong&gt; in the sidebar of each application and use the &lt;code&gt;Go to App action&lt;/code&gt; for &lt;strong&gt;On Click&lt;/strong&gt; event handler.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-8.37.14-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-8.37.14-AM.png" alt="release" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: For making this change you'll need to create a new version from the released version first and then release it again for this change to be included.&lt;/p&gt;




&lt;p&gt;Voila!! 🎉 You have successfully built an HR Management system that includes a suite of 4 different applications 🚀&lt;/p&gt;

&lt;p&gt;If you have any queries related to building applications with ToolJet or just want to hang out in the community of low-code applications builders just drop us a Hi in our &lt;a href="https://join.slack.com/t/tooljet/shared_invite/zt-r2neyfcw-KD1COL6t2kgVTlTtAV5rtg" rel="noopener noreferrer"&gt;Slack Community&lt;/a&gt;. 🚀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Build HR Management System using MongoDB and ToolJet (Part 3: Employees and Requests)</title>
      <dc:creator>Shubhendra Singh Chauhan</dc:creator>
      <pubDate>Mon, 11 Jul 2022 11:33:55 +0000</pubDate>
      <link>https://forem.com/tooljet/build-hr-management-system-using-mongodb-and-tooljet-part-3-employees-and-requests-4m3e</link>
      <guid>https://forem.com/tooljet/build-hr-management-system-using-mongodb-and-tooljet-part-3-employees-and-requests-4m3e</guid>
      <description>&lt;h2&gt;
  
  
  Employees and Requests
&lt;/h2&gt;

&lt;p&gt;Clone the last app that we built and remove all the widgets from the main section and remove all the queries that are there. Don't forget to rename the application from &lt;code&gt;Company Calendar&lt;/code&gt; to &lt;code&gt;Employees and Requests&lt;/code&gt; from the top left of the app editor.&lt;/p&gt;

&lt;p&gt;Assuming that you connected the MongoDB datasource, we can now start building the UI of the main section and then add the queries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build the user interface
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In the last two apps, we disabled the respective button on the sidebar, similarly, in this app, we will disable the &lt;code&gt;Employees and Requests&lt;/code&gt; button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-4.57.13-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-4.57.13-AM.png" alt="employees" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Drag a &lt;strong&gt;Tabs&lt;/strong&gt; widget into the Canvas, and edit its properties. Set the Tabs field value to:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{{[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;title:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Employees'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;id:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;title:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Leave&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Requests'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;id:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Set the Default tab to &lt;code&gt;0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;We will be placing the widgets inside the &lt;strong&gt;Employees&lt;/strong&gt; and &lt;strong&gt;Leave Requests&lt;/strong&gt; tabs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-6.06.12-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-6.06.12-AM.png" alt="employees" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Employees Tab
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;First, drag a &lt;strong&gt;modal&lt;/strong&gt; widget somewhere below the tabs widget&lt;/li&gt;
&lt;li&gt;Place a &lt;strong&gt;button&lt;/strong&gt; inside the &lt;strong&gt;Employees&lt;/strong&gt; tab, edit the button's property and add an event handler to show a modal, and choose the modal that you added on the canvas (modal1)&lt;/li&gt;
&lt;li&gt;Click on the button to show the modal, now you can drag the widgets inside the modal to create a form-like UI. I have used &lt;strong&gt;text&lt;/strong&gt; widgets for labels, &lt;strong&gt;text input&lt;/strong&gt; widgets for the input fields, and then a &lt;strong&gt;button&lt;/strong&gt; widget &lt;code&gt;Add&lt;/code&gt; . The button widget will have &lt;strong&gt;two event handlers&lt;/strong&gt;: one for closing the &lt;strong&gt;modal1&lt;/strong&gt; and the other that will trigger the query for &lt;strong&gt;adding the employee details&lt;/strong&gt; into the database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-6.07.13-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-6.07.13-AM.png" alt="employees" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, add a &lt;strong&gt;table&lt;/strong&gt; widget inside the Employees tab. Set the &lt;strong&gt;Table data&lt;/strong&gt; field value to &lt;code&gt;{{queries.allEmployees.data}}&lt;/code&gt; - we haven't created the queries yet. The table will be populated once we create the queries.&lt;/li&gt;
&lt;li&gt;Go to the &lt;strong&gt;Add Columns&lt;/strong&gt;, add 4 columns &lt;strong&gt;First Name, Last Name, Email, Phone,&lt;/strong&gt; and set their &lt;strong&gt;keys&lt;/strong&gt; as &lt;code&gt;first_name&lt;/code&gt;, &lt;code&gt;last_name&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, and &lt;code&gt;phone&lt;/code&gt; respectively.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-6.13.37-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-6.13.37-AM.png" alt="employees" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, switch the tab to &lt;strong&gt;Leave requests&lt;/strong&gt;. Place a second modal somewhere below the tabs widget, drag a &lt;strong&gt;listView&lt;/strong&gt; widget inside the tab, and set the List data field value to &lt;code&gt;{{queries.leaveRequestsList.data}}&lt;/code&gt; . Add an event handler on the &lt;strong&gt;ListView&lt;/strong&gt; widget - select Event as &lt;strong&gt;Row Clicked&lt;/strong&gt;, Action as &lt;strong&gt;Show Modal&lt;/strong&gt;, and choose the modal i.e. &lt;strong&gt;modal2&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-6.23.44-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-6.23.44-AM.png" alt="employees" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, click on the row to &lt;strong&gt;show the modal&lt;/strong&gt;. Inside the modal, add &lt;strong&gt;two buttons: Approve&lt;/strong&gt; or &lt;strong&gt;Reject&lt;/strong&gt;. These two buttons will be used to accept or reject the leave request raised by the employees.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-6.45.04-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-6.45.04-AM.png" alt="employees" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We will add the widgets inside the listview once we have created the queries.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Build the queries
&lt;/h3&gt;

&lt;h4&gt;
  
  
  addEmployee
&lt;/h4&gt;

&lt;p&gt;This query will be used to insert a document into a collection. With this query, we will add an employee to the database.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new MongoDB query, select the &lt;code&gt;Insert One&lt;/code&gt; operation, enter the Collection name &lt;code&gt;employees&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Enter the Document data as an object: &lt;code&gt;{ first_name: "{{components.textinput1.value}}", last_name: "{{components.textinput2.value}}", email: "{{components.textinput4.value}}", phone: "{{components.textinput3.value}}" }&lt;/code&gt; - here we are using JS to get the values from the widgets that we have added inside the &lt;strong&gt;modal1&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Hit the &lt;strong&gt;Save&lt;/strong&gt; button, not the Save &amp;amp; Run because executing the query now will fail as there are currently no values in the form.&lt;/li&gt;
&lt;li&gt;Once the query is saved, you can click on the &lt;code&gt;Add Employee&lt;/code&gt; button to show up the form modal and then edit the Add button inside it. Add another event handler to run the &lt;code&gt;addEmployee&lt;/code&gt; query on the &lt;strong&gt;On Click&lt;/strong&gt; event.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F07%2FScreenshot-2022-07-08-at-6.50.33-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F07%2FScreenshot-2022-07-08-at-6.50.33-AM.png" alt="employees" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  allEmployees
&lt;/h4&gt;

&lt;p&gt;This query will return all the employees in the database.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new MongoDB query, select &lt;code&gt;Find Many&lt;/code&gt; operation, and enter the Collection name as &lt;code&gt;employees&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Go to the &lt;strong&gt;Advanced&lt;/strong&gt; tab and enable the &lt;code&gt;Run query on page load&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Save &amp;amp; Run&lt;/strong&gt; button on the query manager and as soon as the query runs you'll see the table gets populated with the employees' data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  leaveRequestsList
&lt;/h4&gt;

&lt;p&gt;This query will return the list of those documents that have leaves status set as &lt;code&gt;requested&lt;/code&gt; and will display it on the listview widget.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a MongoDB query, select &lt;code&gt;Find Many&lt;/code&gt; operation, enter the Collection name as employees&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Filter&lt;/strong&gt; field, set &lt;code&gt;{"leaves.status": "requested"}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Save &amp;amp; Run&lt;/strong&gt; the button to save and fire up the query.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F07%2FScreenshot-2022-07-08-at-7.12.08-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F07%2FScreenshot-2022-07-08-at-7.12.08-AM.png" alt="employees" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, that we have our data, we can add widgets to the list view widget. I have used the text widgets. For Labels use text widgets with HTML heading/bold tag for formatting. For displaying the query data use:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;First Name&lt;/strong&gt;: &lt;code&gt;{{listItem.first_name}}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Last Name&lt;/strong&gt;: &lt;code&gt;{{listItem.last_name}}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phone&lt;/strong&gt;: &lt;code&gt;{{listItem.phone}}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Email&lt;/strong&gt;: &lt;code&gt;{{listItem.email}}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Leave Requested from&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;listItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;leaves&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;leave&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;leave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;requested&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
&lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;leave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;start_date&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DD-MM-YYYY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;No. of Days&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;litItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;leaves&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;leave&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;leave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;requested&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
&lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;leave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;leave_days&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F07%2FScreenshot-2022-07-08-at-7.25.58-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2F2022%2F07%2FScreenshot-2022-07-08-at-7.25.58-AM.png" alt="employees" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can now successfully release this version of the application by clicking the &lt;strong&gt;Release&lt;/strong&gt; button on the top right of the app editor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-7.30.25-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog.tooljet.com%2Fcontent%2Fimages%2Fsize%2Fw1600%2F2022%2F07%2FScreenshot-2022-07-08-at-7.30.25-AM.png" alt="employees" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;




</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
