Skip to main content
Version: 4.7.0

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

ParameterTypeRequiredDefaultDescription
$idstringYes-Unique identifier (Now.ID['value'])
conditionstringYes-Encoded query expression to evaluate
labelstringNo-Display label for this branch
annotationstringNo-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

ParameterTypeRequiredDefaultDescription
$idstringYes-Unique identifier (Now.ID['value'])
conditionstringYes-Encoded query expression to evaluate
labelstringNo-Display label for this branch
annotationstringNo-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

ParameterTypeRequiredDefaultDescription
$idstringYes-Unique identifier (Now.ID['value'])
annotationstringNo-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

ParameterTypeRequiredDefaultDescription
itemsTArrayYes-Array to iterate (use data pill with array type)
$idstringYes-Unique identifier (Now.ID['value'])
annotationstringNo-Description/comment
bodyfunctionNo-Callback receiving each item

Supported Data Pill Types

  • 'array.object' — For lookUpRecords results 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

ParameterTypeRequiredDefaultDescription
$idstringYes-Unique identifier (Now.ID['value'])
annotationstringNo-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

ParameterTypeRequiredDefaultDescription
$idstringYes-Unique identifier (Now.ID['value'])
annotationstringNo-Description/comment

wfa.flowLogic.endFlow

Immediately terminates flow execution.

Signature

wfa.flowLogic.endFlow(
params: {
$id: string,
annotation?: string
}
)

Parameters

ParameterTypeRequiredDefaultDescription
$idstringYes-Unique identifier (Now.ID['value'])
annotationstringNo-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

ParameterTypeRequiredDefaultDescription
$idstringYes-Unique identifier (Now.ID['value'])
annotationstringNo-Description/comment
blocks() => voidYes-One or more arrow functions to execute in parallel

Important Constraints

  • No nestingdoInParallel cannot be used inside another doInParallel block
  • 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 doInParallel block are not accessible outside it. To use an action output after the block, assign it to a flow variable inside the block using wfa.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

ParameterTypeRequiredDefaultDescription
$idstringYes-Unique identifier (Now.ID['value'])
annotationstringNo-Description/comment
handlersobjectYes-Object with try and catch arrow functions

Handlers Object

PropertyTypeRequiredDescription
try() => voidYesArrow function containing code to attempt
catch() => voidYesArrow function to execute if try block fails

Important Notes

  • Both try and catch must be arrow functions
  • tryCatch blocks 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 tryCatch block are not accessible outside it. To use an action output after the block, assign it to a flow variable inside the block using wfa.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

ParameterTypeRequiredDefaultDescription
$idstringYes-Unique identifier (Now.ID['value'])
annotationstringNo-Description/comment
variablesVYes-Flow variables schema (pass params.flowVariables)
valuesobjectYes-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

ParameterTypeRequiredDescription
$idstringYesUnique identifier (Now.ID['value'])
annotationstringNoDescription/comment
variablesFlowSchemaType<S>YesFlow variables schema — always pass params.flowVariables
valuesPartial recordYesKey/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.flowVariables as the variables argument — never construct a custom object.
  • Only the keys listed in values are 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

OperatorDescriptionExample
=Equalspriority=1
!=Not equalsstate!=6
<Less thanpriority<3
<=Less or equalpriority<=2
>Greater thanpriority>3
>=Greater or equalpriority>=2

Empty/Not Empty Operators

OperatorDescriptionExample
ISEMPTYField is emptyassigned_toISEMPTY
ISNOTEMPTYField has valueassignment_groupISNOTEMPTY

List Operators

OperatorDescriptionExample
INIn liststateIN1,2,3
NOT INNot in liststateNOT IN6,7

String Operators

OperatorDescriptionExample
STARTSWITHStarts withnumberSTARTSWITHINC
ENDSWITHEnds withemailENDSWITH@company.com
CONTAINSContainsshort_descriptionCONTAINSfailed

Logical Operators

OperatorDescriptionExample
^ or ^ANDLogical ANDpriority=1^active=true
^ORLogical ORpriority=1^ORpriority=2
^NQNew 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.