“It is by logic that we prove, but by intuition that we discover.”
— Henri PoincarĂ©
One of the reasons that I built my little Flow Designer Scratchpad was to keep track of an index while I looped through items in an Array. After doing a few of those, I decided it would be even nicer if I had some kind of iterator Action that would do the work of incrementing the index and returning the Array element at the current index. I already had the scratchpad to store all of the data necessary to support an iterator, so it seemed as if I could write some kind of Action that would take a Scratchpad ID, an Iterator ID, and an Array as input and use that information to set up the ability to iterate through the Array provided. As usual, I decided to put the bulk of the code in a Script Include to keep the actual code in the Action down to the absolute minimum. Here is the SNHStringArrayUtils that I came up with:
var SNHStringArrayUtils = Class.create();
SNHStringArrayUtils.prototype = {
initialize: function() {
},
createIterator: function(scratchpadId, interatorId, stringArray) {
var response = {};
var snhspu = new SNHScratchpadUtils();
response = snhspu.setScratchpadProperty(scratchpadId, interatorId, interatorId);
if (response.success) {
if (Array.isArray(stringArray)) {
var iterator = {};
iterator.index = 0;
iterator.array = stringArray;
response = snhspu.setScratchpadProperty(scratchpadId, interatorId, JSON.stringify(iterator));
if (response.success) {
response.message = 'Array Interator ' + interatorId + ' successfully created';
}
} else {
response.success = false;
response.message = 'String Array parameter is missing or invalid';
}
}
return response;
},
iteratorNext: function(scratchpadId, interatorId) {
var response = {};
var snhspu = new SNHScratchpadUtils();
response = snhspu.getScratchpadProperty(scratchpadId, interatorId);
if (response.success) {
var iterator = {};
try {
iterator = JSON.parse(response.property_value);
} catch (e) {
response.success = false;
response.message = 'Unable to parse JSON string containing iterator details';
}
if (response.success) {
if (iterator.index >= 0 && iterator.index < iterator.array.length) {
response.current_value = iterator.array[iterator.index];
response.current_index = iterator.index;
iterator.index++;
response.has_next = (iterator.index < iterator.array.length);
response.message = 'The current value at index ' + response.current_index + ' is ' + response.current_value;
snhspu.setScratchpadProperty(scratchpadId, interatorId, JSON.stringify(iterator));
} else {
response.success = false;
response.message = 'Current index value out of range';
}
}
}
return response;
},
type: 'SNHStringArrayUtils'
};
Basically, there are two methods, one for each of the two Flow Designer Actions that I intend to build. The first one is createIterator, which is used to initialize a new iterator, and the second is iteratorNext, which will support the Action that you will invoke inside of your loop to get the next item in the Array. Both utilize an existing scratchpad, so you will need to create that prior to invoking these Actions, and both require an Iterator ID, which is just a unique key to be used in storing the iterator data in the scratchpad. The createIterator action would be called once outside of the loop, and then the iteratorNext function would be called inside of the loop, usually right at the top to pull out the next value in the array.
The iterator itself is just a two-property object containing the array and the current value of the index. This is converted to a JSON string and stuffed into the scratchpad using the passed Iterator ID as the key. When creating the iterator, we set the index value to zero, and in the next Action, after using the index to get the current element, we increment it and update the scratchpad. Now that we have the basic code to support the two Actions, we need to go into the Flow Designer and create the Actions.
The Create Array Iterator Action seems like the logical place to start. That will will need three Inputs defined.
… and it will need two Outputs defined, a success indicator and an optional error message detailing any failure to perform its intended function.
In between the Inputs and Outputs will be a simple Script step, where we will produce the Outputs by passing the Inputs to our associated Script Include function.
var snhsau = new SNHStringArrayUtils();
var result = snhsau.createIterator(inputs.scratchpad_id, inputs.iterator_id, inputs.string_array);
for (var key in result) {
outputs[key] = result[key];
}
That’s pretty much all there is to that. We can test it using the Test button up at the top of the Action Editor, but first we will need a Scratchpad. We can take care of that real quick by hitting the Test button on the Create Scratchpad Action and then grabbing the Scratchpad ID from the Outputs. With our Scratchpad ID in hand, we can now test our Create Array Iterator Action.
So far so good. now we just need to do the same thing for the Array Iterator Next Action, and we’ll be all set.
This is pretty much a rinse and repeat kind of thing, with fewer Inputs, but more Outputs. When it comes time to test, we can use the Scratchpad ID and Iterator ID from our last test, and then run it through a few times to see the different results at different stages of the process. Rather that go through all of that here, I will just bundle everything up into an Update Set, and you can pull it down and play with it on your own.
Note: With the introduction of Flow Variables, this component is no longer necessary.