retool basics - Write JavaScript
Introduction
There are some scenarios that we need to write JavaScript code to solve, such as transforming data, displaying data conditionally, fetching data from multiple queries, controlling UI components, and setting Temporate state, and proficiency in writing JavaScript is a necessary skill for us to create a retool app!
Objective
Learn to write JavaScript query in retool
Learn to assign values to UI components using JavaScript
Prerequisites
register a Retool account
Create a blank app in Retool
It is recommended to use the latest version of Chrome to access Retool
Hello World!
Let's start with a simple example
A. Click button to create a new query
B. select JavaScript Query from the drop-down menu.
A. Enter the following code in the multi-line text input control
// print hello world
console.log('Hello, world!')
B. Click Debug to open Debug Tools
C. Click Preview to run JavaScript query
D. Console tab displays log message
We have learned how to write a JavaScript query in retool through this step, and then we will introduce the basics of JavaScript, so that we can build a good learning foundation to go further.
JavaScript Basics
There are many versions of JavaScript, so here is an introduction to ECMAScript 6 (abbreviated as ES6).
For the sake of brevity, I'm only going to cover common points here. For a more comprehensive understanding of JavaScript, read https://www.w3schools.com/js/js_es6.asp
Variables and types
JavaScript defines variables through the let
and const
keywords, the difference between these two is that let defines a variable whose value will change later, and const defines a variable whose value will not change again.
Here are some examples of variable definitions
const myNumber = 3; // a number type
const myString = "Hello, World!" // a string type
const myBoolean = true; // a boolean type
let myArray = ["apple", "banana"]; // an array type
let myObject = {
a: "I am a",
b: "I am b"
}; // an Object type
Variables have various value types, as shown in the code above, including numbers (integers, decimals), strings, booleans, arrays, and objects.
There is one special type of value to be aware of, null.
null can be assigned as a value, e.g.
let myVariable = "aa";
console.log(myVariable);
myVariable = null;
console.log(myVariable);
You can run the above code in retool to see the result.
array
You can store many values in the array type by defining the array using the following syntax
let myArray = [1, 2, 3];
Variables in an array are called elements, and you can access elements in an array using an index starting at 0. If you already know where in the array the element you are trying to access is located, you can use the following syntax to access it
console.log(myArray[1]); // print 2
Arrays are flexible in JavaScript in that they can be assigned directly even if the element at the corresponding position does not exist.
let myArray = [];
myArray[3] = "hello";
console.log(myArray);
The result in retool is as follows
If the element at the corresponding position does not exist, it will be printed as undefined.
We can insert and remove elements at the end of the array
let myStack = [];
myStack.push(1);
myStack.push(2);
myStack.push(3);
console.log(myStack);
The result in retool is as follows
Now we remove some elements at the end of the array
console.log(myStack.pop());
console.log(myStack);
The result in retool is as follows
How to get the length of the array? You can access the length attribute of the array variable, sample code is as follows
let myStack = [];
myStack.push(1);
myStack.push(2);
myStack.push(3);
console.log(myStack.length); // print 3
Object
JavaScript objects are key-value structures that can be accessed or assigned to elements of the object using the operators .
or []
to access or assign values to the elements of the object, the sample code is as follows
let personObject = {
firstName : "John",
lastName : "Smith"
}
personObject.age = 23; // assign a value
personObject["salary"] = 14000; // assign a value
console.log(personObject.age)
console.log(personObject)
The result in retool is as follows
Operator
Math operators
console.log(3 + 5); // Addition, print 8
console.log(3 - 5); // Subtraction, print -2
console.log(3 * 5); // Multiplication, print 15
console.log(3 / 5); // Division, print 0.6
console.log(5 % 3); // Remainder, print 2
Comparison operators
console.log(3 < 5); // print true
console.log(3 > 5); // print false
console.log(3 == 5); // print false
let a = 3;
let b = "3";
console.log(a == b); // print true
console.log(a != b); // print false
console.log(a === b); // print false
console.log(a !== b); // print true
Variable a is of numeric type and variable b is of string type.
If you use ==
to compare, JavaScript will not judge whether the variables are of the same type or not, but only whether the values are the same or not, so it outputs true
, if you need to judge that the two values are not equal, please use !=
If you use ===
to compare, JavaScript will determine both the value and the type, so it outputs false
, if you need to determine the value or type of two variables are not equal, use !==
Ternary operator
let a = "ming";
console.log(a == "ming" ? "I am ming" : "A"); // print I am ming
console.log(a != "ming" ? "B" : "C"); // print C
Logical Operators
let foo = 1;
let bar = 3;
let moo = 2;
console.log(foo < bar && moo > bar); // print false
console.log(foo < bar || moo > bar); // print true
console.log(!(foo < bar)); // print false
&&
means and, both expressions have to be true for the final result to be true
||
means or, one of the two expressions has to be true for the final result to be true
!
means not, which reverses the result of the expression, e.g. true is reversed to false.
Conditional statements
if/else
if/else
allows us to determine whether an expression is true or false, and execute the code accordingly.
let foo = 1;
let bar = 2;
if (foo < bar) {
console.log("foo < bar");
} else if (foo == bar) {
console.log("foo == bar");
} else {
console.log("foo > bar");
}
The above code prints foo < bar
, and you can change the values of the variables foo and bar to see the result.
switch
The switch
statement is used to perform different actions based on different conditions.
let rank = "Sergeant";
switch(rank)
{
case "Private":
case "Sergeant":
console.log("action1");
break;
case "Commander":
console.log("action2");
break;
case "Captain":
console.log("action3");
break;
default:
console.log("other");
break;
}
In the above code, when the value of the variable rank is Private
or Sergeant
, action1
is printed, and when the value is Commander
, action2
is printed.
The default keyword means that when no other value matches, the other
will be printed here.
The switch
statement evaluates an expression, matching the expression's value against a series of case
clauses, and executes statements after the first case
clause with a matching value, until a break
statement is encountered
You can execute the following code to experience the differences
let rank = "Sergeant";
switch(rank)
{
case "Private":
case "Sergeant":
console.log("action1");
case "Commander":
console.log("action2");
break;
case "Captain":
console.log("action3");
break;
default:
console.log("other");
break;
}
Loop
Loops can execute a block of statement a number of times.
Loop to execute code multiple times
for statement, let i = 0
means declare variable i
and initial value is 0
, i < 5
means if i
is less than 5
it will loop five times;, i++
means every time it loops i
will be incremented by 1.
for (let i = 0; i < 5; i++) {
console.log(`Hi, i is ${i}`);
}
The result in retool is as follows
Cyclic Access to Arrays
Accesses the elements of an array at incremental indexes.
let myArray = ["A", "B", "C"];
for (let i = 0; i < myArray.length; i++)
{
console.log("myArray,index " + i + " ,value " + myArray[i]);
}
The result in retool is as follows
Cyclic access to objects
Object.entries
function will turn the object variable into an array. An array of the given object's own enumerable string-keyed property key-value pairs. Each key-value pair is an array with two elements: the first element is the property key (which is always a string), and the second element is the property value
let personObject = {
firstName : "John",
lastName : "Smith",
gender: "female"
}
console.log(Object.entries(personObject))
for (const [key, value] of Object.entries(personObject)) {
console.log(`${key}: ${value}`);
}
The result in retool is as follows
Function
The role of the function is to allow us to reuse the code and organize the code structure, the function has input and output, define the function of the sample code as follows
function greet(name)
{
return "Hello " + name + "!";
}
console.log(greet("Eric")); // print Hello Eric!
The result in retool is as follows
asynchronous(Async / Await)
Asynchronous code can be programmed using the async
/ await
keywords
async
marks a function as an asynchronous task, and await
means waiting for the asynchronous function to complete.
example1. The await
keyword is not used.
async function slowTask() {
return new Promise((resolve) => {
// Wait 10 seconds and then execute the task
setTimeout(function() {
console.log("I finished the job")
resolve();
}, 10000)
});
}
slowTask();
console.log("aa")
The Promise
in the above code is the syntax for declaring asynchronous code in JavaScript. a Promise
is an object representing the eventual completion or failure of an asynchronous operation.
The purpose of the slowTask function is to print that I finished the job
in 10 seconds. If you don't use the await keyword to wait for the asynchronous task to finish, the slowTask function is triggered and console.log("aa")
is executed immediately afterward, so aa
appears before I finished the job
.
The result of the above code in retool is as follows
example2. Use the await
keyword to wait for an asynchronous task to complete
async function slowTask() {
return new Promise((resolve) => {
// Wait 10 seconds and then execute the task
setTimeout(function() {
console.log("I finished the job")
resolve();
}, 10000)
});
}
await slowTask();
console.log("aa")
The result in retool is as follows
Assigning Values to UI Controls
create a new JavaScript query with the name query2
Type the following code
let a = "Hello, Nice to meet you";
return a
A. JavaScript query’s name is query2
B. JavaScript code
C. save the query, and run once
We need to run this query once, and we'll need to use the results of this query later.
click button: add ui component
type “text”
drag text to main frame
Enter the following code
👋 **Hello {{ query2.data. }}!**
final result
query2
is the name of the JavaScript query, the result of the query is referenced by the expression query2.data
, {{ }}
represents the use of JavaScript expressions, which reads the value of the JavaScript variable query2.data.
** **
is the bold syntax of Markdown, see https://www.markdownguide.org/cheat-sheet/ for Markdown syntax, you can use markdown to control the content style of Retool's Text control.
utility libraries
Third-party utility libraries
Retool automatically imports the following utility libraries.
refer to https://docs.retool.com/apps/scripting-events/guides/javascript#libraries
Retool utils methods
Global methods for interacting with Retool apps, controlling behavior, and formatting or parsing data. For example, to open a new tab in a browser, to open a Retool application, to download a file, etc., see https://docs.retool.com/reference/apps/global/methods
Commonly used code examples
Here are some commonly used sample code with comments, easy to learn and copy-paste. The code here can be executed in a retool JavaScript query.
JavaScript Object Read/Write
get method
// Using the lodash library's get function
// read tableVersion.selectedRow.data.content,Returns the empty string if the value does not exist
_.get(tableVersion, "selectedRow.data.content", "")
map method
// Using the lodash library's map function
function square(n) {
return n * n;
}
// Processes the elements of the array in turn, returning a new array.
_.map([4, 8], square);
// => [16, 64]
let users = [
{ 'user': 'barney' },
{ 'user': 'fred' }
];
// Processes the elements of the array sequentially. Returns the array, the elements of which are the values read according to the path
_.map(users, 'user');
// => ['barney', 'fred']
time handling
// Formatting time with the moment library
// Formatted myInfo.createdAt as 2022-10-02 21:32:23
moment(myInfo.createdAt).format("YYYY-MM-DD HH:mm:ss")
// Calculates the difference between myInfo's two times, finishedAt - createdAt, and returns milliseconds.
moment(myInfo.finishedAt).diff(moment(myInfo.createdAt))}} ms
Summary
In this article we learned how to write JavaScript queries in retool and how to assign values to UI controls, this article is very difficult and has a lot of knowledge, please practice more in retool!
In the next article, I will explain how to use the API in retool.