String Interpolation and JSON Flatten/Unflatten
Introduction
When defining properties for a trigger or workflow step, String Interpolation uses variable values to create new values.
String Interpolation can be used in:
- Trigger Property Values
- Trigger Property Names
- Workflow Step Properties and Output Properties
- Command
- Set
- Start Workflow
- Send Event
- End
- Workflow Property Names
- Workflow Conditional Execution Statements
Examples
Properties are defined by setting a name to a value. By default the value is treated as a literal string.
Name | Value | Final Value |
---|---|---|
fullName | John Smith | John Smith |
Curly brackets are used to indicate that variable replacement should be performed. if firstName is John and lastName is Smith then:
Name | Value | Final Value |
---|---|---|
fullName | {firstName} {lastName} | John Smith |
If the variable does not exist then it is evaluated as empty string. If middleName does not exist:
Name | Value | Final Value |
---|---|---|
fullName | {firstName}-{middleName}-{lastName} | John--Smith |
Functions
A function can be used in the string interpolation by preceding the function name with a question mark:
Name | Value | Final Value |
---|---|---|
fullName | {?Left(firstName, 'h')} | Jo |
Any variable name used in a function must not need to be surrounded by curly brackets. For example the variable first-name would not be valid as the parameter to the function in the example above.
Objects and Arrays
The variables in a trigger or workflow are simple string dictionaries but the syntax of an array or object as used in other languages can be used. To make it easy pass an entire "object" or "array" in a trigger or workflow step the value syntax of a single variable in curly brackets
(e.g. name = "newname", value = "{name}"
) will perform these steps in order to find a value:
- Lookup the variable "name". If found - use its value.
- Look for all variables that start with "name." or "name[".
- If any are found copy each value to the destination variables and remove any existing variables that start with the destination prefix ("newname." and "newname[")
- If the destination name is different from the source name the name is changed (see examples below)
- Use the default value of empty string
Object Example
The following variables could be set for a "person" object:
Name | Value |
---|---|
person.firstName | John |
person.lastName | Smith |
person.fullName | John Smith |
person.office | 102 |
In a trigger or workflow step to pass all of the "person" variables, changing the name to "value", use the following syntax:
Name | Value | Destination Values |
---|---|---|
value | {person} | value.firstName = "John" value.lastName = "Smith" value.fullName = "John Smith" value.office = "102" |
Array Example
The following variables could be set for an array of attachments:
Name | Value |
---|---|
attachments.count | 2 |
attachments[0].name | data1.txt |
attachments[0].data | abc123 |
attachments[1].name | data2.txt |
attachments[1].data | def456 |
In a trigger or workflow step to pass the entire "attachment" array, leaving the name the same:
Name | Value | Destination Values |
---|---|---|
attachments | {attachments} | attachments.count = "2" attachments[0].name = "data1.txt" attachments[0].data = "abc123" attachments[1].name = "data2.txt" attachments[1].data = "def456" |
Array Indexing
All variable names are strings: name, index, etc. During condition evaluation the variable name is resolved by looking up the variable name to retrieve the value.
Variable names can contain square brackets such as name[0] or attachments[1].data. If a variable name lookup fails because it does not exist and the variable name contains square brackets, an attempt is made to do variable substitution and attempt the lookup again. This allows using variables as array indexes.
The variable name inside of the array index must not start with a number: digit (0-9), plus: +, minus: -, or dot (.).
Functions can be used inside of an array index but:
- The expression must be inside of curly brackets to be parsed correctly
- The function must be preceded by a question mark (?)
Example:
The variables are:
index = '2'
name[0] = 'name_zero'
name[1] = 'name_one'
name[2] = 'name_two'
name[3] = 'name_three'
data[2] = '1'
Value | Final Value | Variable Lookups Performed |
---|---|---|
{name[2]} | name_two | name[2] - succeeded |
{name[index]} | name_two | name[index] - failed name[2] - succeeded (name_two) |
{name[?Add(index, 1)]} | name_three | name[3] - succeeded (name_three) |
Arrays can be nested up to five levels deep:
Value | Final Value | Variable Lookups Performed |
---|---|---|
{name[data[index]]} | name_one | name[data[index]] - failed data[index] - succeeded (1) name[1] - succeeded (name_one) |
Multiple array replacements can be performed in one variable name. Up to ten replacements can occur.
Added variables:
index2 = '1'
name[2].titles[1] = 'foo'
Value | Final Value | Variable Lookups Performed |
---|---|---|
{name[index].titles[index2]} | foo | name[index].titles[index2] - failed name[2].titles[1] - succeeded (foo) |
JSON Flattening and Unflattening
Flattening Output Data
The data returned from the request, if it is json, will be flatten and added to the response as multiple properties prefixed with "content".
Here are some example of flattening:
HttpContent | WF Response |
---|---|
Example of data flattened from https://randomuser.me/api/:
|
|
Unflattening Input Data
Data passed as payload for the POST command of the HttpRequest Adapter must be set as multiple properties of the command step, just like a reverse flatten of the json.
All properties that must be part of the payload, must be prefixed with 'content'. The JSON will be constructed from them.
Here are some example of unflattening:
WF Request | HttpContent |
---|---|
Rules for unflattening data:
- Properties can be set either simple, complex or collections
- Once a property has been set of a type, it cannot be set to another type (collections cannot have nested properties, simple properties cannot be collections, etc)
- The order in which the properties are set is not important, but when specifying collections, all indexes must be provided (cannot unflatten collection if only items 0, 1 and 4 are provided)
- When unflattening data, all values are string; there are no int, bool and no null values (string empty is allowed)