Loops

3 ways to create loops

📘

Learn more about arrays in this guide and in documentation.

👍

See this example project you can import into your environment.

What is a loop?

Loops are used to repeat the same operation for multiple elements.

In Automate, we usually loop through (or iterate through) arrays (including arrays of objects).

Loops are used to perform 2 types of operation:

  • edit elements of an array,
  • print messages that include information stored in an array.

In this guide, we will focus on the second type of loops.

Intro: 3 ways to create loops in Automate

Each of the method described in this guide has its own advantages and limitations:

MethodExample
1. Printing a list in Response using foreach
Use foreach keyword in Say block to print a response composed from each element of an array.
- ✅ Easy to use
- ✅ Limited to single block and response
- ❌ Not fully customizable
2. Looping through blocks
Use this method to loop through the same set of blocks for each element of an array.
For example, after printing each of the appointments, we can ask the user if they want to cancel it.

- ✅ Each element is printed in a separate block
- ❌ Requires more blocks and caution
3. Loops with JavaScript
Use JS in Memory for complete freedom in composing printable responses stored in arrays that can be later printed as a response in Say block.

- ✅ Fully customizable responses
- ✅ Can be used in single blocks as well as with 3. Looping through blocks method
- ❌ Usually requires more blocks
- ❌ Requires JavaScript skills

Before you begin - create or import an array

Loops are operations performed on multiple elements.

Array is a type of data that stores multiple elements, so loops are used to iterate through arrays. In other words, any loop requires an array.

📘

Learn more about arrays in this guide and in documentation.

In our example, we create an array by saving it to Memory using Custom block:

Custom block with Array initialization

Custom block with Array initialization

Create new variable with data

Create new variable with data

This is the value we saved to memory.appointments:

[
    {
        "key": "8",
        "date": "2022-10-18",
        "time": "10:00 am",
        "purpose": "Internist",
        "patient_id": "319319",
        "clinic_city": "London",
        "doctor_name": "Isabel White",
        "clinic_address": "68 Mill Lane"
    },
    {
        "key": "26",
        "date": "2022-10-17",
        "time": "2:00 pm",
        "purpose": "Dentist",
        "patient_id": "319319",
        "clinic_city": "London",
        "doctor_name": "Brook Ward",
        "clinic_address": "11 Alexander Road"
    },
        {
        "key": "2",
        "date": "2023-01-14",
        "time": "1:30 pm",
        "purpose": "Eye doctor",
        "patient_id": "319319",
        "clinic_city": "London",
        "doctor_name": "Elise Hill",
        "clinic_address": "652 Grove Road"
    }
]

memory.appointments is an array of objects, which means that each element of an array is an object containing properties like key, date, clinic_address etc.

After saving it to memory, we can access it or print it in Responses anytime.

Using arrays of objects in Responses

Before we procede to loops, it is important to understand how arrays of objects work and how we can access them to present (print) valuable, pretty Responses to the user.

To access or print only one of the elements of an array, we can specify it by using its index, for example memory.appointments[0] will return the first element of this array:

    {
        "key": "8",
        "date": "2022-10-18",
        "time": "10:00 am",
        "purpose": "Internist",
        "patient_id": "319319",
        "clinic_city": "London",
        "doctor_name": "Isabel White",
        "clinic_address": "68 Mill Lane"
    }

Let’s go even further: to access only a specific property of the first element of memory.appointments, for example the doctor’s name, we could use dot notation, just like that: memory.appointments[0].doctor_name. This would just return:

Isabel White

As you can see, this is finally something that we can actually show or read to the client! 😊

For example, Response composed like that:

Your {memory.appointments[0].purpose} is {memory.appointments[0].doctor_name}.

Would show to the user this message:

Your Internist is Isabel White.

In many cases, this will be enough to present valuable information to the user.

But what if we want to present more than one element in a Response or a series of Responses, for example a list of available appointments?

To do this, we need loops.

1. Printing a list in Response using foreach

Foreach is used to iterate through an array, transform it's elements, combine them together and print as a string (with new line character as a delimiter).

  1. Start the expression with foreach keyword. It is followed by the variable's name of your choosing and the keyword in. You will use this selected name to access the current element in an array. For example, the start of the expression can look like that: foreach product in or foreach element in.
  2. Next, input an array that you want to iterate through (or a variable storing an array, eg. nlu.variablesList).
  3. Finally, compose an interpolated string in a new line and inside double quotation marks. Access and modify the current element of an array with the name you selected by interpolating (throwing in) an expression inside curly brackets.

1.1. Basic examples

We can use foreach to loop through a simple array (not having any objects as elements) to print them in the Response while changing it in some way by doing so.

1.1.1. Multiply numbers

In the following example, we loop through an array of numbers and multiply them by 2. The result is a list of multiplied elements printed in the Response:

foreach element in [1, 2, 3]
"{element * 2}"

// Result:
`
2
4
6
`

1.1.2. Add a prefix to strings

In the following example, we loop through an array of strings and add a prefix before each of them. The result is a list of pretty elements, perfect for adding them to Response:

foreach element in [23, 45, 9]
"no. {element}"

// Result:
`
no. 2
no. 4
no. 6
`

1.1.3. List appointments

👀

See this example project in Automate you can import into your environment.

Using foreach keyword, we can print a pretty list of the appointments stored in memory.appointments as a bot Response. The following expression will present to the user all of the appointments, and we can decide exactly which properties we want to show.

Response input in flow editor

Response input in flow editor

Example output in webchat

Example output in webchat

2. Looping through blocks

There are certain situations in which we have to implement a loop in our flow using more than just one block with a little bit of code.

For example, if after printing each of the appointments from the list, we want to ask the user if they want to cancel it, we can’t limit ourselves to one block. We have to loop through a set of blocks.

Looping through blocks means using the same set of blocks for as many times as there are elements in an array we use as our data.

Each time we use this set of blocks, the next element from an array is used to compose Responses and/or make flow decisions.

Example: list appointments while asking about cancelling them

👀

See this example project in Automate you can import into your environment.

Result of a loop through blocks

Result of a loop through blocks

2.1. Create blocks that will perform as loop

  1. Create a variable in memory that will serve as counter
  2. After each iteration add +1 to counter variable and check if counter value is equal to length of Array
  3. If it is equal finish the loop if not repeat step 2.
Loop example in flow module using blocks

Loop example in flow module using blocks

3. Loops with JavaScript

JavaScript is a model programming language which advanced features and control structures. If you have programming skill using JavaScript may be the best option for you.

🚧

Using JavaScript requires programming skill that your co-workers may not have. Use it with caution, when other methods are not possible.

Here is an example script that is available in tutorial project available to download here:

(function(){
const appointments = memory.appointments;
const app_length = appointments.length;
//const appointments = JSON.parse(JSON.stringify(memory.appointments));
const printArr = appointments.slice(0,5).map( (el,index) => 

// --------------- start of message ----------------- //'

`${index + 1}. ${index == 0 ? "Your closest" : index == app_length - 1 ? "Your last" : "Your next"} appointment is scheduled for ${el.date} at ${el.time}.
You're seeing ${el.doctor_name} (${el.purpose}).
Address: ${el.clinic_address}, ${el.clinic_city}
`
// --------------- end of message ----------------- //
)

return printArr;

}())
Usage of JavaScript used in Custom block in variable initialization

Usage of JavaScript used in Custom block in variable initialization