Flow control
AutomatorScript supports most of the flow control mechanisms available in JavaScript. On this page, we will zoom in on two of them: conditions and loops.
Standard flow control is done by conditions and loops. More sophisticated flow control is done by functions and exception handling and will be covered in later chapters.
The structural element of any kind of flow control is a block of execution code. A block clamps a set of execution commands together by surrounding it with curly braces. Blocks can be nested at any needed level. A block defines the scope of a variable.
Conditions
A condition enables to split the flow of execution to different blocks of execution code. The execution of these blocks depends on the result of the condition.
A condition is introduced with the keyword if.
if (condition) {
//executed if condition is truthy
} else { // optional - else part can be omited
// executed if condition is falsy
}
Example condition
let d = new Date()
let day = d.getDay()
if (day === 0) {
log('sunday')
} else {
log('other day')
}
A condition is started with if and parantheses containing any mathematical condition that can be written with code. The curly brace block after the condition is only executed if the condition equals to a truthy value.
It is possible to add an else keyword followed by an own curly brace block. This is only executed if the condition equals to a falsy value.
falsy means anything that is false, 0, null, undefined, or computes to this values
truthy means anything that is true, existent, NOT falsy, or computes to this values.
Example truthy / falsy
let obj = {
x: 5
}
if (obj && obj.x) {
log('obj exists and there is a value in obj.x that is different to 0')
} else {
log('no value - perhaps obj is null or obj.x is 0, null or undefined')
}
Since the value of obj.x is a valid integer different to 0 the true block of the condition is executed.
Switch statements
Sometimes you might find yourself writing a long chain of if-else statements to do something based on the value of a variable, for example:
if (status === 'assigned') {
handleAssigned();
} else if (status === 'accepted' || status === 'in_progress') {
handleInProgress();
} else if (status === 'completed') {
handleCompleted();
} else {
// ...
}
In such a case, you could use a switch statement instead:
switch (status) {
case 'assigned':
handleAssigned();
break;
case 'accepted':
case 'in_progress':
handleInProgress();
break;
case 'completed':
handleCompleted();
break;
default:
// ...
}
The break statements after each case are important. If you don't include them, execution will continue with the code
in the next case. This is called "fall-through". Fall-through always happens, unless there is a break or return
statement. In the above example, there is only one case where the break statement is left out: the accepted case,
which should be handled by the same block of code as the in_progress case.
More information about switch statements can be found on MDN.
Loops
A loop is a block of code that is executed multiple times. The number of executions is defined by rules and conditions with different introducing keywords depending on the type of loop.
type of loop
- 'for' loop
- 'for of' loop
- 'while' loop
- 'do while' loop
Loops can be left at any time with the keyword break.
for loop
Example 'for' Loop
for (let x = 0; x < 5; x++) {
log('value of x :', x)
}
A for loop is mostly used to iterate over a defined range of numbers.
There are three parts in the parentheses of a for loop:
- Initialization (e.g.:
let x = 0) - Condition (e.g.:
x < 5) - Final Expression (e.g.:
x++)
After initialization the loop is executed as long the condition computes truthy. After each execution the final expression is executed.
Multiple initialization values are possible. Even multiple final expressions are allowed.
Example 'for' Loop
for (let x = 0, y = 5; x < y; x++, y--) {
log('value of x :', x)
log('value of y :', y)
}
Important: The condition is checked before the execution of the block. So if the condition is falsy, the block is never executed.
for of loop
To iterate over a list of any kind use the for of loop
Example 'for of' Loop
let list = [1, 4, 6, 34, 62]
for (let element of list) {
log('value of element :', element)
}
The elements can also be objects.
Example 'for of' Loop
for (let task of workflow.tasks) {
log('task :', task.subject)
}
Important: If the list is empty, the block of the loop is never executed!
'while' and 'do while' loop
These loops are used to repeat a block as long a specific condition is truthy.
Example 'while' Loop
let sum = 0
while (sum < 1000) {
let x = 150 // calculate something into x
sum = sum + x
}
The value of sum is checked and the block is executed as long as the conditon is truthy. This means that the block also can be executed never, if the value of sum is bigger than 1000 in the beginning.
Example 'while' Loop
let sum = 1500
while (sum < 1000) {
// this is never executed
let x = 150
sum = sum + x
}
In a 'do while' loop the condition is checked at the end - so the block is executed once for sure
Example 'do while' Loop
let sum = 0
do {
let x = 150 // calculate something into x
sum = sum + x
} while (sum < 1000)
These loop variants are also called "head-controlled" or "foot-controlled", depending on the position of the condition.