In its basic form the command sequence inside a Step is a simple, straight line of commands being evaluated. However, that is not all there is to it - some commands may be conditional, some may be repeated, and some commands specifically work as components of other commands.
Some commands can be set to be parents or children of other commands. This creates a relationship between the commands, usually in the way that the child commands affect the functionality of their parent somehow, but it can also be the other way around. In the documentation pages of each command there may be the sections "Parent commands" and "Child commands" - these list the other commands that the command has these special relationships with.
As an example, the command setMap creates a Map value, which is by default empty. In its documentation,
setMap has one listed child command - addMapEntry (which then has
setMap listed as a parent). An
addMapEntry command may therefore be added as a child for
setMap, making it so that the created Map starts out with the entry defined by the child command as its content instead of being empty. This relationship is marked as optional, as both
addMapEntry can function without each other as well.
In the Template editor, commands that are children of other commands are displayed below their parents with more indentation, like
addMapEntry in the image above. The parent commands also have a triangle displayed on the left side of them, which can be clicked to hide or show the child commands. To make a command a child of another, simply drag the child-to-be on top of its desired parent command.
setMap the child relationship provides optional functionality, the relationships may alternatively be marked as required in the command documentation. As another example, the mail command sends an email message. However, it cannot do that unless it has child commands defining properties of the message - the most critical being the to command, defining the destination address of the message. Below is a typical example of
Similar to how
While the commands have defined sets of possible children, it is possible to actually use any command as a child. While this doesn't serve much purpose in most cases, it can come very useful with the logic control commands, such as if and forEach. One of the design reasons why some properties of what is clearly a single operation - such as sending an email - is broken into a parent and child commands rather than being a single command with multiple attributes is basically this use of control commands to control the children. Here's the previous example modified a bit to give the email more CC addresses.
What occurs here is that
forEach, the looping command, causes the
cc child to be evaluated for every item in the "emailCCList" Collection, therefore adding every address in that Collection into the generated email message's CC field. The
if command could be used in a similar way to make certain child commands conditional, so maybe the attachment child for example wouldn't be evaluated in some cases. This also illustrates the fact that these child-parent relationships work across commands in the hierarchy between the parent and child, they don't have to be directly linked.
However, do note that only commands that have child commands listed in their documentation have the ability to evaluate child commands. Commands that do not have any listed children do not expect to have any and so will leave any child commands given to them unevaluated.
The control command if along with the command trio choose, when and otherwise exist for creating conditional sections into command sequences. Based on some condition, a set of commands does or does not get evaluated, altering how the command sequence proceeds. Here's an example of the
if command being used to control if the logic is to create a Chatter post or not.
As you can see, the commands are made conditional through command hierarchy, with the conditional commands being children of the condition-checking control command
if. Should the variable "postToChatter" have a Boolean value of "true", the postFeedItem command and its own child will be evaluated - should "postToChatter" have some other value, the
if will not evaluate its children, causing no Chatter-posting to happen.
otherwise work very similarly to
if, but allow the creation of multiple conditional sections of which only one will have its commands evaluated. This works well when you have a choice with multiple answers with different outcomes, and also if you'd like something to happen if a condition is not met, which
otherwise is for. Here's an example using these commands to select a theme based on a favorite color:
What happens here is that if "favoriteColor" is "Orange", "theme" is set to "Sunset" and the
choose command is finished - none of the remaining options are checked since a successful result occurred. Should "favoriteColor" not be "Orange", the command moves on to check if the color is "Blue" instead and if so, sets the theme to a different kind. If it isn't that either, the
otherwise section will activate and set the theme to whatever value the "defaultTheme" variable holds. This is a typical
otherwise structure, as the conditions are closely related, checking the same variable. For comparison, here's the same conditional structure using
if instead of
choose and its children:
It doesn't look too different, aside from the
if playing the role of
otherwise - its condition has to be the reverse of the conditions preceding it. Quite a bit more complicated than just using
otherwise. This is also less efficient performance-wise, as the conditions of all three
if commands are processed regardless of whether the theme was already set, while the
otherwise section will not be processing the remaining options at all if the condition of a
when resolves into "true".
A loop is a section that repeats a set of commands for a number of times. The only source of loops within a command sequence is the control command forEach, which specifically exists for doing something with all items of a Collection. The loop is defined through child hierarchy - all the child commands of a
forEach are the ones that will be repeated as the
forEach goes through each item of the Collection one by one. Below is an example of using
forEach to define multiple attachments for a new Chatter post.
In this example the "documentIds" variable's value can be assumed to be a Collection containing record ids of document files in Salesforce. The
forEach command will repeat the createFeedAttachment command placed as its child once for every document id in the Collection, resulting in all the documents being attached to the new post. Any command can be used within a loop, but do note that certain commands of slow performance being looped can produce notable slowdown. Certain commands may also have limits to how many times they can be evaluated, and Salesforce commands can produce Salesforce API requests which organizations have specific maximum limits for. Loops can cause the commands within to get repeated for numerous times - from tens to even thousands of times - so be aware of the potential size of your loop and the commands placed within.
The evaluation of a command sequence within a Step or any other logic container may not always reach the end of the sequence. This can happen through specific commands that have a sequence-interrupting characteristic, as mentioned in their documentation. The commands next and return for example are such, as their evaluation causes the evaluation of the current Step or Function to end immediately. Any commands placed after them in a command sequence are therefore useless - this is why these commands are generally the last ones in the sequence, or inside conditional structures.
Another way for a sequence to get interrupted is a command error. Normally a command sequence keeps proceeding normally regardless of commands producing errors, but if the Step has an error-handling route defined, the command sequence will be interrupted if any command within the Step produces an error.