Skip to main content

SSJS Loops

Let's dive into limited looping options of the SSJS.

Working with arrays and objects is one of the selling points of SSJS vs AMPScript. And the primary way to utilize those structures is to loop over them. While SSJS doesn't have all the magic of the modern JavaScript, it still has much more to offer than single FOR available in AMPScript.

For Loops

For

The classic for loop might be a bit long to write, but it has a lot of excellent properties:

  • Works with break and continue statements for better looping control.
  • Both initial and increment expressions can do multiple things (examples available below).
  • Condition is not limited to iterable length (although it is the most popular way).
  • Fast across various scenarios.
Example of for loop iterating over an array
for (var i = 0; i < array.length; i++) {
Write(i); // Returns the current iteration
Write(array[i] + '<br/><br/>'); // Returns the value of current element
};

Let's break the script down to five steps each for loop follows:

  1. Execute initial expression (var i = 0 in the above example).
  2. Evaluate the condition (i < array.length). If it is false - the loop terminates. If true:
  3. The statement within the loop is executed (Write(array[i])).
  4. Finally, the increment expression will evaluate (i++).
  5. The loop goes back to step 2 until it is false.

To optimize speed, cache the length used for condition. By assigning it to a variable in initial expression, the loop won't have to calculate the length on each iteration.

Initial expression assigns array.length to a variable to cache it
for (var i = 0, range = array.length; i < range; i++) {
Write(i); // Returns the current iteration
Write(array[i] + '<br/><br/>'); // Returns the value of current element
};

You can get more logic within the for declaration to, for example, have a cleaner statement within the loop:

Provide itemValue variable instead of just current iteration
for (var i = 0, itemValue = array[i], range = array.length; i < range; i++, itemValue = array[i]) {
Write(itemValue + '<br/><br/>'); // Returns the value of current element
};

As ES6 for...of loop is not available in SSJS, you will use this one in most scenarios.

For in

for...in loop in modern JavaScript is used nearly exclusively for debugging. It is because it loops not only over standard values but also over object prototype methods and properties.

In SSJS however, the ES6 for...of loop is not available. Object.keys() or Object.entries() also does not exist. This makes the for...in the only solution for iterating over objects.

for (var key in object) {
Write(key + '<br/><br/>'); // Returns string name of the current key
};

In simple scripts created in SSJS you shouldn't have issues with the prototype methods and properties, however, if you encounter any issues (or want to code defensively), use hasOwnProperty method:

for (var key in object) {
if (object.hasOwnProperty(key) && key != '_type') {
Write(key + '<br/><br/>');
};
};

Remember to use for...in only for looping over objects. For any other scenario classic for loop is both safer and more powerful.

You Should Know

If you ever use for...in loop for an array, remember that the loop-counter variable will return a string instead of a number. For example '0' for first array item instead of 0.


While Loops

While

A while loop executes its statement as long as the condition evaluates to true.

Infinite while loop
var run = true;
while (run === true) {
Write('To the infinity and beyond!');
};

To break out of while loop, there must be logic within it that will change the condition to false (or a break statement):

var run = true;
var i = 0;
while (run === true) {
Write('To the infinity and beyond!');
i++;
if (i > 10) {
run = false;
};
};

or just:

This loop has the same outcome as the one above
var run = true;
var i = 0;
while (i <= 10) {
Write('To the infinity and beyond!');
i++;
};

while loop is the best option for iterating over big arrays.

Do While

Same as while, but the code runs once before evaluating the condition.

do {
Write('Running!');
} while (run === true);

Perfect when you need to run an API call, check whether there are more pages of outcomes and act accordingly.

You Should Know

JavaScript support labels for loops. It allows you to name each loop for even better control with both continue and break statements.

Labelled loop example using a nested for loops
MainLoopLabel:
for (var i = 0; i < array.length; i++) {
// Logic
SecondaryLoopLabel:
for (var j = 0; j < array[i].length; j++) {
// Logic
if (array[i][j] === 'important') {
break MainLoopLabel;
};
};
};

As you can see, in the first line we added a label for the first for loop. Then, in the statement within the second for loop, we used break followed by the label. Once executed, it will break both for loops, even if there were still iterations in the main one. The same approach works with the continue statement.