Flow Logic
The wfa.flowLogic namespace provides control flow operators for branching, looping, and flow control within Flow and Subflow bodies.
Usage Pattern
All flow logic constructs follow this invocation shape:
wfa.flowLogic.<construct>(
{ $id: Now.ID['logic_id'], ...params },
callback?
)
wfa.flowLogic.if
Evaluates a condition and executes the callback if true.
Signature
wfa.flowLogic.if(
params: {
$id: string,
condition: string,
label?: string,
annotation?: string
},
body: () => void
)
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
$id | string | Yes | - | Unique identifier (Now.ID['value']) |
condition | string | Yes | - | Encoded query expression to evaluate |
label | string | No | - | Display label for this branch |
annotation | string | No | - | Description/comment |
wfa.flowLogic.elseIf
Evaluates a condition if previous conditions were false. Must follow if or elseIf.
Signature
wfa.flowLogic.elseIf(
params: {
$id: string,
condition: string,
label?: string,
annotation?: string
},
body: () => void
)
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
$id | string | Yes | - | Unique identifier (Now.ID['value']) |
condition | string | Yes | - | Encoded query expression to evaluate |
label | string | No | - | Display label for this branch |
annotation | string | No | - | Description/comment |
wfa.flowLogic.else
Executes callback if all previous conditions were false. Must follow if or elseIf.
Signature
wfa.flowLogic.else(
params: {
$id: string,
annotation?: string
},
body: () => void
)
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
$id | string | Yes | - | Unique identifier (Now.ID['value']) |
annotation | string | No | - | Description/comment |
wfa.flowLogic.forEach
Iterates over an array, executing the callback for each item.
Signature
wfa.flowLogic.forEach<TArray>(
items: TArray,
config: {
$id: string,
annotation?: string
},
body?: (item: ExtractArrayElement<TArray>) => void
)
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
items | TArray | Yes | - | Array to iterate (use data pill with array type) |
$id | string | Yes | - | Unique identifier (Now.ID['value']) |
annotation | string | No | - | Description/comment |
body | function | No | - | Callback receiving each item |
Supported Data Pill Types
'array.object'— ForlookUpRecordsresults and object arrays'array.string'— For string arrays (no item parameter)
wfa.flowLogic.exitLoop
Immediately exits the enclosing forEach loop.
Signature
wfa.flowLogic.exitLoop(
params: {
$id: string,
annotation?: string
}
)
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
$id | string | Yes | - | Unique identifier (Now.ID['value']) |
annotation | string | No | - | Description/comment |
wfa.flowLogic.skipIteration
Skips the current iteration and continues with the next item.
Signature
wfa.flowLogic.skipIteration(
params: {
$id: string,
annotation?: string
}
)
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
$id | string | Yes | - | Unique identifier (Now.ID['value']) |
annotation | string | No | - | Description/comment |
wfa.flowLogic.endFlow
Immediately terminates flow execution.
Signature
wfa.flowLogic.endFlow(
params: {
$id: string,
annotation?: string
}
)
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
$id | string | Yes | - | Unique identifier (Now.ID['value']) |
annotation | string | No | - | Description/comment |
wfa.flowLogic.doInParallel
Executes multiple code blocks in parallel within a flow.
Signature
wfa.flowLogic.doInParallel(
params: {
$id: string,
annotation?: string
},
...blocks: (() => void)[]
)
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
$id | string | Yes | - | Unique identifier (Now.ID['value']) |
annotation | string | No | - | Description/comment |
blocks | () => void | Yes | - | One or more arrow functions to execute in parallel |
Important Constraints
- No nesting —
doInParallelcannot be used inside anotherdoInParallelblock - Minimum 1 block — At least one parallel block is required
- Each block is an arrow function:
() => { ... } - Datapill scope limitation — Action output datapills captured inside a
doInParallelblock are not accessible outside it. To use an action output after the block, assign it to a flow variable inside the block usingwfa.flowLogic.setFlowVariables, then reference the flow variable outside.
wfa.flowLogic.tryCatch
Creates a try-catch block for error handling in flows.
Signature
wfa.flowLogic.tryCatch(
params: {
$id: string,
annotation?: string
},
handlers: {
try: () => void,
catch: () => void
}
)
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
$id | string | Yes | - | Unique identifier (Now.ID['value']) |
annotation | string | No | - | Description/comment |
handlers | object | Yes | - | Object with try and catch arrow functions |
Handlers Object
| Property | Type | Required | Description |
|---|---|---|---|
try | () => void | Yes | Arrow function containing code to attempt |
catch | () => void | Yes | Arrow function to execute if try block fails |
Important Notes
- Both
tryandcatchmust be arrow functions tryCatchblocks can be nested- The catch block executes only if an error occurs in the try block
- Datapill scope limitation — Action output datapills captured inside a
tryCatchblock are not accessible outside it. To use an action output after the block, assign it to a flow variable inside the block usingwfa.flowLogic.setFlowVariables, then reference the flow variable outside.
wfa.flowLogic.appendToFlowVariables
Appends element(s) to array-typed flow variables.
Signature
wfa.flowLogic.appendToFlowVariables<V>(
params: {
$id: string,
annotation?: string
},
variables: V,
values: Partial<{
[K in keyof V]: V[K] extends Array<infer E>
? E | E[] | unknown[] | string
: never
}>
)
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
$id | string | Yes | - | Unique identifier (Now.ID['value']) |
annotation | string | No | - | Description/comment |
variables | V | Yes | - | Flow variables schema (pass params.flowVariables) |
values | object | Yes | - | Key/value pairs where keys are array variable names |
Value Types
For each array variable, you can append:
- Single element —
{ arrayVar: singleElement } - Array of elements —
{ arrayVar: [elem1, elem2, elem3] } - Data pill —
{ arrayVar: wfa.dataPill(...) } - Template string —
{ arrayVar: 'template expression' }
Important Constraints
- Array.Object only — Only supports
FlowArray({ elementType: FlowObject(...) })variables - Array elements must be objects or datapill expressions — When appending an array literal, each element must be an object or a datapill expression
- Compile-time safety — TypeScript enforces that target variables are arrays
wfa.flowLogic.setFlowVariables
Assigns values to flow-scoped variables declared in the Flow or Subflow config flowVariables property. This is a type-only helper — it is erased at runtime and only influences the TypeScript type-checker.
Signature
wfa.flowLogic.setFlowVariables(
definition: { $id: string, annotation?: string },
variables: FlowSchemaType<S>,
values: { [K in keyof FlowSchemaType<S>]?: FlowSchemaType<S>[K] | string }
)
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
$id | string | Yes | Unique identifier (Now.ID['value']) |
annotation | string | No | Description/comment |
variables | FlowSchemaType<S> | Yes | Flow variables schema — always pass params.flowVariables |
values | Partial record | Yes | Key/value pairs of variables to set. Omitted keys are unchanged. |
Value Types
For each variable entry in values, you can supply:
- Typed literal —
{ myVar: 'hello' },{ count: 42 } - Data pill —
{ myVar: wfa.dataPill(params.trigger.current.short_description, 'string') } - Template string —
{ myVar: 'template expression' }
null and undefined are not valid — omit the key instead of setting it to null.
Important Notes
- Always pass
params.flowVariablesas thevariablesargument — never construct a custom object. - Only the keys listed in
valuesare updated; other flow variables retain their current values. - Flow variables are scoped to the current flow or subflow execution — they are not visible to called subflows.
Condition Syntax Reference
Flow logic conditions use ServiceNow encoded query format.
Comparison Operators
| Operator | Description | Example |
|---|---|---|
= | Equals | priority=1 |
!= | Not equals | state!=6 |
< | Less than | priority<3 |
<= | Less or equal | priority<=2 |
> | Greater than | priority>3 |
>= | Greater or equal | priority>=2 |
Empty/Not Empty Operators
| Operator | Description | Example |
|---|---|---|
ISEMPTY | Field is empty | assigned_toISEMPTY |
ISNOTEMPTY | Field has value | assignment_groupISNOTEMPTY |
List Operators
| Operator | Description | Example |
|---|---|---|
IN | In list | stateIN1,2,3 |
NOT IN | Not in list | stateNOT IN6,7 |
String Operators
| Operator | Description | Example |
|---|---|---|
STARTSWITH | Starts with | numberSTARTSWITHINC |
ENDSWITH | Ends with | emailENDSWITH@company.com |
CONTAINS | Contains | short_descriptionCONTAINSfailed |
Logical Operators
| Operator | Description | Example |
|---|---|---|
^ or ^AND | Logical AND | priority=1^active=true |
^OR | Logical OR | priority=1^ORpriority=2 |
^NQ | New query (OR group) | priority=1^NQstate=2 |
For usage patterns, examples, best practices, and end-to-end flow logic examples, see the Flow Logic Guide.