Skip to main content
Version: Latest (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.