For each loop

See also: Break loop

Event action – Abstract

Purpose: Repeats a block of event actions for a list of objects or a specified number of repetitions.


The For each loop event action repeats a block of event actions either for a list of entries or for a number of repetitions defined by a numerical value.

The following variables are available for the event actions within the loop, to which the system automatically assigns values at the beginning of each iteration:

Variable name

Type

Automatic value assignment at the beginning of an iteration

$index

Integer

The current iteration index starting at 0

$length

Integer

The number of planned repetitions (depending on the value Resolver for entities parameter).

$first

Boolean

true in the first iteration ($index=0), otherwise false

$last

Boolean

true in the last scheduled iteration, otherwise false

NOTE

  • Within the loop, these variables can be assigned different values by event actions (e.g. Set value or Store value as variable).

  • At the end of an iteration, the current value for the iteration index ($index) is compared with the value valid at the beginning of the iteration. If the current value is lower than the previous one, the variable will be assigned the previous higher value. So the iteration index can only be 'moved' forward and not backward, which could cause an endless loop.

  • Value assignments to the $length variable during an iteration are basically 'lost' at the end of the iteration. If a loop is executed over a list of entries, the value for $length is determined only once (before the start of the first iteration). Manipulating the list by removing or adding entries during iterations is possible in principle, but does not change the value of $length (see below: Clone list for manipulation parameter).

  • As long as the current (possibly manipulated) iteration index satisfies the condition $index < ($length - 1) at completion, the loop continues with a new iteration with an iteration index increased by 1.

    • A loop can therefore be aborted after the current iteration is completed, by assigning as an iteration index a value that does not satisfy the condition $index < ($length - 1). From a pragmatic point of view, the value $length is often used for this purpose.

    • The Break loop event action can be used to abort a loop immediately (without completing the current iteration).

  • The variables managed by the system apply exclusively within the loop. So, for example, an event handler that follows a For each loop cannot access the number of repetitions executed via the $length variable. In order for corresponding information to be available after the loop is completed, the corresponding value must be explicitly assigned to a variable by an event action within the loop, which the system does not assign automatically.

Configuration

images/download/attachments/177911614/image-2024-9-16_15-44-48-version-1-modificationdate-1726494287457-api-v2.png

The optional Save Object in variable parameter can be used to define the name of a variable that provides access to the outer reference object in the context of which the For each loop event action is executed as a whole within the loop.

  • The corresponding value assignment applies only within the loop. Any existing association for the same variable outside of the loop is only temporarily overlaid by this.

  • The parameter is only relevant if the loop is to iterate over a list of entries, since then within the loop a different entry is considered as the reference object in each iteration.

  • If, on the other hand, only a specified number of repetitions is to be executed (see Resolver for entities parameter), then the outer reference object also applies within the loop as the reference object.

The optional Resolver for entities parameter defines the iteration scheme for the loop. The following cases are to be distinguished:

  1. The parameter defines a resolver that returns a numerical value (>0) at runtime. Then this value – if necessary after rounding down to an integer – determines the number of iterations of the loop to be executed. In all iterations, the outer reference object is considered the reference object.

  2. The parameter defines a resolver that returns a list of entries at runtime. Then the loop iterates over these entries. Within the loop, a different entry is considered the reference object in each iteration.

  3. The parameter does not define a resolver ('no value'). Then the outer reference object is passed to the loop. If this is a list of entries, the loop iterates over these entries.

NOTE◄ In case 3, if the outer reference object is not a list, the loop is not executed. The attempt to pass a single numerical value (in the sense of case 1) as an outer reference object to a loop fails with an error message.

The Clone list for manipulation option should be used if the closure refers to a list of entries (case 2 or 3) that is to be manipulated in the course of the iterations by removing or adding entries:

  • If the option is set, then a 'clone' of the list is created before the start of the loop, which is then iterated over. Manipulations of the list by adding or removing entries (see Modify list or List item) then have no influence on the iteration scheme.

  • If the option is not set, then list manipulations are also possible. However, they can lead to unexpected results or errors when processing the loop, because the iteration scheme can be affected by changes to the list. Adding or removing entries moves existing entries and changes the 'length' of the list if necessary, while neither the iteration index ($index) nor the number of scheduled repetitions ($length) automatically respond to such changes. For example, if more entries are removed from a list than are added, the iteration scheme will eventually become stalled when the next entry is to be assigned for a new iteration, causing an error. This can be prevented by adjusting the iteration index (e.g. assigning $index=$length via Set value) to end the loop early. However, it is not possible to increase the number of iterations to be executed by accessing $length if more entries should be added than removed within the loop.

Below the parameters, the event actions to be executed in the loop can be added via the images/s/-95e2zf/9012/8yg2g7/_/images/icons/emoticons/add.svg symbol.

Examples

Loop over a given number of repetitions

Within a loop, a Custom action event 'Allocate container' is triggered for a given shipment so often that the number of containers allocated as a result matches the number of Euro pallets determined for the shipment.

The For each loop event action is parameterized within an event handling for the 'Shipment' business object as shown on the right:

  • In the Resolver for entities parameter, a Calculate value resolver is used to specify the formula for calculating the number of containers required. The value of the pallets variable, which here defines the number of Euro pallets in the shipment, is divided by the number of pallets per container (here: 11) and the result is rounded up by the ceil()function.

    IMPORTANT◄ Via concatenation, the value field from the calculated data type 'Unit Number' must be set via an Object property resolver, since the 'Unit Number' is not automatically converted into an integer (for the iterations).

  • In the block for the event actions, a Dispatch action event event action is executed for the 'Allocate container' event. The outer reference object, in this case the 'Shipment', which is also to be passed on to the event here, applies as the reference object within the loop.

images/download/attachments/177911614/image-2024-9-17_7-47-52-version-1-modificationdate-1726552072087-api-v2.png

Loop over a list of entries

When a specific working state is assigned to a shipment, an event handler should display the names of all indicator attributes set for that shipment in one notification.

Within an event handling triggered by the working state in question, a For each loop event action is configured as shown on the right:

  • The Save shipment in variable parameter is used so that the shipment can be accessed via the shipment variable name when the notification is created.


  • In the Resolver for entities parameter, a list of all 'Flag attributes' is first obtained via Attribute (Resolvers) value resolver.

  • The concatenated Rule list resolver should then return Resolve all as a list from this list for which the 'flag attribute' (flagValue) has the value true , i.e. the flag is set.

  • From the list of set flag attributes, a list of the corresponding flag types (see Flag type) is obtained by concatenation with a Collect values resolver, over which the loop is to iterate.

The reference object within the loop is therefore a Flag type in each case.

images/download/attachments/177911614/image2021-2-24_16-20-11-version-1-modificationdate-1726494187735-api-v2.png

Inside the loop we configure a Show alert (Popup) event action as shown on the right:

  • 'Warning' is selected here as the Type of notification, since indicators are only assigned for 'critical' features within the shipment.

  • In the Title content builder, a Value from localization resolver accesses the Localization, which specifies the 'Flag type' class as a Bundle. Within this bundle, the 'Flag types' are identified by the Name, which can be taken directly from the 'Name' (name) field of the 'Flag type' entry within the loop. Via each Object property resolver (collapsed in the image) this 'name' is assigned as a Resource and also as a Default value, so that for a non-localized Flag type the internal name appears.

  • In the Message content builder, the field 'ID' (id) of the shipment is accessed here for demonstration purposes, which is only possible within the loop via the shipment variable, since the Flag type defined by the Resolver for entities otherwise applies as the reference object.

NOTE◄ Instead of or in connection with the internal ID of the shipment, for example, the value of a reference attribute with an order number or another characteristic that sufficiently identifies the shipment could also be issued.

images/download/attachments/177911614/image-2024-9-17_9-2-9-version-1-modificationdate-1726556529297-api-v2.png

Runtime example:

images/download/attachments/177911614/image2021-2-24_16-24-2-version-1-modificationdate-1726494187730-api-v2.png

Loop with 'Abort criterion'

A shipment data input form shall offer users the possibility to enter the weight of a number of packages for the same shipment item in a small popup dialog. In the end, only the aggregated total weight is to be stored in the shipment item.

When the 'Weight entry' is opened for an item, the dialog shown on the right is to be called cyclically to query weights of individual packages until the user acknowledges the dialog with the default value of '0', i.e. without entering a weight, via the OK button.

As shown in the image on the right, the total weight entered so far should be displayed in the title bar, while a list of the entries made so far for each package should appear line by line in the dialog itself for checking purposes.

NOTE◄ It is assumed that the user only enters whole numbers for the weight. No special precautions are taken with regard to the input format for this example.

images/download/attachments/177911614/image2021-2-24_16-29-3-version-1-modificationdate-1726494187727-api-v2.png

Configuration:

An event handling is initiated via a Custom action event, which can be triggered when clicking on a Button in the item level of the input form. This event handling contains the configuration shown on the right for a For each loop:

  • The Save shipment in variable parameter is used to save the shipment position in the targetLineItem variable as a reference object.

  • In the Resolver for entities, a long value of 999 is defined for the number of repetitions of the loop, so that the loop is repeated 'endlessly' (until the termination condition is reached).

  • Within the loop, a Set value event action is executed, which already contains the most important 'operations' of the procedure. The Calculate value resolver (right) adds to the value of the total_weight_kgs variable the value of the item_kgs variable, whose definition (below the calculation expression) uses a User prompt type resolver to request a concrete package weight from the user via a dialog.

  • Details of the User prompt are not presented here in more detail. However, it is essential for the example that the concrete, single return value from the User prompt is passed by concatenation to a Store value as variable resolver, which assigns it to the input variable. The abort criterion for the loop refers to this variable further below.

  • The numerical values entered via a dialog are to be added up in the total_weight_kgs variable until the loop is aborted. To do this, the actual value must be extracted from the 'Unit Number' data type using the Object property resolver.

images/download/attachments/177911614/image2021-2-24_16-36-34-version-1-modificationdate-1726494187725-api-v2.png

  • Immediately after the weight is added, another Set value event action is executed to attach the single return value of the User prompt to the string variable log according to a similar principle from iteration to iteration. Via this variable, the 'history' of inputs enters the message of the User prompt resolver (see example above). With each iteration, a Concat strings resolver (right) adds the value of input as part of a formatted new text line structured with a literal text, so that the user can gradually track inputs that have already been cleared, just like a desktop calculator with a printer.

images/download/attachments/177911614/image2021-2-24_16-37-32-version-1-modificationdate-1726494187713-api-v2.png

  • Subsequently, an If then else event action is used to check the abort criterion – namely, the entry of the default value '0'. This is done by the Variable rule type, as shown on the right.
    NOTE◄ Since the Variable rule is passed only in case of an exact match with the string '0', entering '000' or text characters without a value would have no terminating effect.

  • The abort of the loop (before the 999th iteration) is achieved by assigning the value of the loop variable $length to the loop variable $index, so that no further iteration occurs. With this association, the abort works reliably and 'maintenance-free' even if the number of repetitions for the loop should be increased at a later time.

  • The abort criterion takes effect only at the end of the current iteration of the loop, so the following event action (Show alert (Popup)) for notifying the user about the total weight input for the current position is still executed in any case. The variable targetLineItem can be used to access details about the item, for example to display the item number (lineItemId) in the title bar of the message.

  • Assigning the total weight as a value for a suitable typed attribute at the item level (not shown here) can also refer to the targetLineItem variable if it is to be executed within the loop. However, this is not necessary in the example, since the value of the total_weight_kgs variable is also valid beyond the context of the loop and can be transferred to the line item even after completion of the loop and, if necessary, further checks or queries.

images/download/attachments/177911614/image2021-2-24_16-38-25-version-1-modificationdate-1726494187707-api-v2.png