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.
- 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)
.
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
intextInput1
. - To view the value of this variable, select State > simpleVariable. This will display the current state of the variable as shown below.
The variable is defined within the Code > + > Variable and can be seen in the Code list. This provides a variable scoped to the application.
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:
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.
Select current_user
to see the additional attributes that can be accessed:
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.
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.
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.
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.
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)}}
.
Next we need a way to initiate the query, so adding an event handler to button1 to execute the query, forLoopQuery
.
Testing this query, we see that the listBox3
will become populated based on the names in the object.
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.
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.
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.
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.
Select the listBox1
component and examine the properties.
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.
In the JavaScript App example, a new attribute is added to each user object called isActive
. Examine the Before and After jsonExplorer components.
- 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.
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:
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.
- Select
jsonExplorer4
(After) to view the inline script.
- 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.
- Select
jsonExplorer2
(After) to view the inline script.
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:
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.
Select jsonExplorer6
(After), to examine the inline JavaScript. Notice the use of the arrow function as in the map example to simplify the expression.
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.
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.
Select the jsonExplorer8
(After), and look at the inline JavaScript that defines the value.
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
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.