Skip to main content

JavaScript Application

The following JavaScript App provides a sample that demonstrates the use of JavaScript and how those queries are connected to components and event handlers with Retool.

Steps

The following steps focus on accessing Retool and using JavaScript with a Retool App.

  • The fundamentals-js app will be imported as a Retool App.
  • Each section of the app will be closely examined to understand different JavaScript capabilities and how Retool components / event handlers interact.

Create a Retool account and login

Create a Retool account and login to your account as shown below.

Import fundamentals-js app into Retool

Next we will import the Retool fundamentals-sql app into Retool. This application is meant to provide a working example with components, code and event handlers that demonstrate real-world actions that are commonly used in building Retool Apps.

JavaScript App
  • Click the Fundamentals JavaScript App link to download the JSON.
  • Once the template has downloaded go to Retool Home Screen, select Apps > Create > From JSON/ZIP.
  • This will display a dialog to provide the downloaded file, the name of the app and the folder.
  • Select Upload a file and select the downloaded file fundamentals-js.json.
  • Specify an App name, fundamentals-js.
  • Leave Add to folder to None(root).
info

Sometime the application may not display select component values properly (e.g. Loop Output). You will need to select Run query for results to display.

Examine Variables and Globals

At the top of the JavaScript application, we have the Variables and Globals section. When working with Retool, managing state is an important aspect of an application. Retool supports state management within the components, but also provides user-defined variables and globals.

  • Select Edit app to examine the first section in more detail.
  • Enter a value next to simpleVariable of 23 in textInput1.
  • To view the value of this variable, select State > simpleVariable. This will display the current state of the variable as shown below.
simpleVariable

The variable is defined within the Code > + > Variable and can be seen in the Code list. This provides a variable scoped to the application.

Variable settings

The value of this variable is being set through an event handler that takes the input in textInput1 and sets the value of the variable as shown below:

Change handler

Globals within Retool is another way state is stored and they provide additional context such as current_user, RetoolContext and can be examined within State at the bottom of the dialog as seen in the figure.

Globals

Select current_user to see the additional attributes that can be accessed:

current_user state

Examine within the JavaScript app how your fullName is displayed. Select the textInput2 field and you will see the inline JavaScript, {{current_user.fullName}} that is being utilized to populate it.

Inline JS with current_user

Examine Looping and Iterables

The next section provides some examples of handling repeating data via a loop or iterable as shown in the following example.

Loop / Iterables example

On the left-hand side, an example JSON payload that has four items is displayed in the jsonExplorer component. Two examples are provided using a JavaScript For loop and a JavaScript Iterables.

In the For loop, we are using a JS Query defined within Code > forLoopQuery.

JS Query forLoopQuery

Below is the code in the image:

// Determine the length of the array by using the length data property
let length = jsonExplorer13.value.length

// Initialize an empty array
let array = [];

// Execute a loop starting at 0, incrementing via 1 each loop until all the array elements have been processed (e.g. length = 4).
for (let i=0; i < length; i ++){

// Get the name of the current entry being processed
let name = (jsonExplorer13.value[i].name);

// Put the name retrieved into our empty array
array.push(name);
}

// Return the populated array back to whomever called this JS Query
return array;

Next we can see how this code is executed by examining the listBox component.

Run query buttons

Using an eventHandler, we populate the identified listBox (e.g. listBox3) via setting the Data source to the query, forLoopQuery. The value is identified using inline script to {{item}} and {{_.startCase(item)}}.

listBox data source

Next we need a way to initiate the query, so adding an event handler to button1 to execute the query, forLoopQuery.

Button event handler

Testing this query, we see that the listBox3 will become populated based on the names in the object.

Click Run query button

The next example demonstrates an Iterable, that provides the same result but syntactically is simpler. Go to Code > iterableQuery. Examine the code sample below and note the simpler looping mechanism where no start point, limit and increment is provided like in the For loop.

// Initialize a persons object with object in the jsonExplorer component.
let persons = jsonExplorer13.value;

// Initialize an empty array
let array = [];

// Iterate over the persons object by processing one array item at a time
for (const person of persons){

// Get the name of the current person being processed
let name = person.name;

// Put the name retrieved into our empty array
array.push(name);
}

// Return the populated array back to whomever called this JS Query
return array;

Similar to the For loop example, this query will populate a listBox component and needs to be initiated and this is done by adding an event handler that is triggered on click of the button component. Review the listBox4 component data source and button2 event handler.

Examine Conditionals

In the next example we look at conditionals to help determine different paths of execution.

Conditionals example

In this example we use if / else logic but JavaScript supports if / else-if / else logic as well. Similar to the previous example we are looking at the Array of People Objects displayed in jsonExplorer. Examine the query by selecting Code > conditionalCheck.

JS Query conditionalCheck

The following is the code sample provided in the image. If we examine within the For loop the conditional check of if and else is provided. The if statement checks the iterable person and the age attribute. Using JavaScript Comparison Operators, we compare the attribute with an integer value in this example. If the if statement returns false, it executes the else statement. This occurs with the person object Bob and Dave as their ages are below 18 years old.

// Initialize a persons object with object in the jsonExplorer component.
let persons = jsonExplorer12.value;

// Initialize an empty array
let array = [];


// Iterate over the persons object by processing one array item at a time
for (const person of persons){

// Check if person’s age is greater than or equal to 18
if (person.age >= 18){
// Get person’s name and concatenate ‘over 18’
array.push(person.name + " over 18");
}
// For person’s age that is less than 18, execute this section
else{
// Get person’s name and concatenate ‘under 18’
array.push(person.name + " under 18")
}
}
// Return the populated array back to whomever called this JS Query
return array;

Similar to the For loop example, this query will populate a listBox component and needs to be initiated and this is done by adding an event handler that is triggered on click of the button component. Review the listBox2 component data source and button3 event handler.

Examine Ternary Operator

The Ternary Operator example provides an alternate mechanism for performing conditional checks via a streamlined definition. The following simple example, using the JavaScript console, shows two variations of an object, inventoryItem, with a ternary operator determining if stock levels are greater than or equal to 500.

Ternary operator example

In the first case there is insufficient inventory so the false condition is returned. In the second case the stockLevel is sufficient and the true condition is returned. The following image shows the Ternary Operator example where the age of the people is determined and visually displayed.

Ternary operator example

Select the listBox1 component and examine the properties.

listBox data source

In this example, the ternary operator is used to set the color to green or red. The syntax uses a conditional check, item.age >= 18. If true, it sets the value to green, else it sets the value red.

Examine Spread Operator

The Spread Operator example provides a mechanism to copy all or a portion of an array / object to another array / object using the … notation. Items that are found in the second object overwrite the original values where values that are new are appended to the object.

Spread operator example

In the JavaScript App example, a new attribute is added to each user object called isActive. Examine the Before and After jsonExplorer components.

Spread operator example
  • To examine the JavaScript that is used to perform this, select the jsonExplorer10 component as shown below. The JavaScript is inline in this example and defined in the Value section.
Inline JS with map

This JavaScript takes the object/array in jsonExplorer9.value and uses the map method, arrow function and spread operator. The map method and arrow function is explained in more detail in the next section, but effectively is used to transform each element in an array, adding the isActive: true attribute/value to each user.

Examine Methods

Arrow function

Arrow functions provide a concise syntax for writing function expressions in JavaScript. They use the => symbol, allowing for shorter, single-action functions and callbacks. An example of a traditional function is shown below:

function processUsers(userArray){

// Initialize a persons object with object in the jsonExplorer component.
let users = userArray;

// Initialize an empty array
let array = [];


// Iterate over the persons object by processing one array item at a time
for (const user of users){

array.push(user.name)
}
// Return the populated array back to whomever called this JS Query
return array;

In comparison, an arrow function can streamline this to:

const userNames = userArray.map(user => user.name)
return userNames;

map

Array.map() provides a mechanism to convert an array from its current state to a new state. It does this by calling a function on each element in the array. The following example provides a simple representation:

Map example

The example shows an original array of values, a function called sqrFunction that takes the value and performs a square of it and then uses the .map method to execute this function against the origArray.

Examine the map function example as shown below.

Map example
  • Select jsonExplorer4 (After) to view the inline script.
Inline JS with Map
  • For the next example, the Advanced Example section for .map focuses on transforming the price attribute via a simple discount calculation leveraging the spread operator.
Advanced Map example
  • Select jsonExplorer2 (After) to view the inline script.
Inline JS with Map and Spread Operator

filter

Array.filter() provides a mechanism to filter an array from its current state to a new state. It does this by calling a function on each element in the array and looking through all the values that match. The following example provides a simple representation:

Filter example

In this example an array is initialized. A function, valFunction, takes a value in the array and determines if it is larger than the value of 9. The finalArray uses a filter to call the valFunction and return a filtered result as shown, 16 and 10.

In the JavaScript App, the filter tab provides an example of examining each object in the array and determining if the category == “electronics”. If it does, it creates an output array that only includes those items.

Filter example

Select jsonExplorer6 (After), to examine the inline JavaScript. Notice the use of the arrow function as in the map example to simplify the expression.

Inline JS with Filter

find

Array.find() provides a mechanism to filter an array from its current state to a new state. It does this by calling a function on each element in the array returning the first value that matches.

Find example

Examining the example above, we start with origArray identifying several numbers. The findValFunction is looking for values greater than 9. Using the find method and passing in the findValFunction, we identify the first entry that meets this condition. In this case it is the number 11.

In the JavaScript App, select the find tab. In this example we are looking for an employee with a certain employee identifier.

Find example

Select the jsonExplorer8 (After), and look at the inline JavaScript that defines the value.

Inline JS with Find

Examine Libraries

Retool includes out-of-the-box access to common javascript libraries like Lodash, Moment.js, and numbro.js. Below are a few examples of how and when to use them

Libraries example

Moment.js

Moment.js is a popular JavaScript library for parsing, validating, manipulating, and formatting dates. Select the moment tab and review the five examples demonstrating date manipulation.

Lodash

Lodash is a popular JavaScript library that provides utility functions for common programming tasks, including working with arrays, numbers, objects, strings, etc., in a more efficient and easier way. Select the lodash tab and review the five examples provided to better understand how this library can be applied.

numbro.js

numbro.js is a powerful library for formatting and manipulating numbers in JavaScript. Select the numbro tab and review the number formatting example provided to better understand how this library can be applied.