See related
No related articles

JSON data workflow helpers

Last Update: Jan 2025 • Est. Read Time: 5 MIN
To check plan availability, see the pricing page.

JSON data helpers allow you to manipulate, format, and extract information from the JSON data generated or received within workflows.

In this article:

Each

The {{#each}} block helper iterates through an array or object and concatenates each found value into a string.

  • Given steps.1.attributes.data.letters = ["a", "b", "c"] OR {"firstLetter": "a", "secondLetter": "b", "thirdLetter": "c"}
    {{#each steps.1.attributes.data.letters}}test{{/each}} resolves to the string "testtesttest"

The value at each index or key can be accessed using the this instance variable.

  • Given steps.1.attributes.data.letters = ["a", "b", "c"] OR {"firstLetter": "a", "secondLetter": "b", "thirdLetter": "c"}
    {{#each steps.1.attributes.data.letters}}{{this}}, {{/each}} resolves to the string "a, b, c, "

Data path notation can access nested attribute values when working with sequentially nested objects.

  • Given steps.1.attributes.data.letters = [{"letter": "a"}, {"letter": "b"}, {"letter": "c"}] OR {"firstLetter": {"letter": "a"}, "secondLetter": {"letter": "b"}, "thirdLetter": {"letter": "c"}}
    {{#each steps.1.attributes.data.letters}}{{this.letter}}, {{/each}} resolves to the string "a, b, c, "

The trailing comma and whitespace in the above examples may be undesirable in certain scenarios. Fortunately, @first and @last helper variables can be used in conjunction with conditional helpers such as {{#if}} to define behavior on the first or last iteration respectively, allowing a character like a comma to be omitted from the final loop. Learn more

  • Given steps.1.attributes.data.letters = ["a", "b", "c"] OR {"firstLetter": "a", "secondLetter": "b", "thirdLetter": "c"}
    {{#each steps.1.attributes.data}}{{this}}{{#if @last}}{{else}}, {{/if}}{{/each}} resolves to the string "a, b, c"

Additional @index and @key helper variables are also available to represent the current loop iteration number and object attribute name, respectively. 

  • Given steps.1.attributes.data = {"firstLetter": "a", "secondLetter": "b", "thirdLetter": "c"}
    {{#each steps.1.attributes.data}}{{@index}}-{{@key}}: {{this}}{{#if @last}}{{else}}, {{/if}}{{/each}} resolves to the string "0-firstLetter: a, 1-secondLetter: b, 2-thirdLetter: c"

Note: Nested {{#each}} blocks can access iteration variables via depth-based paths. For example, @../index can be used to access and reference the parent index.

As a block helper, {{#each}} has access to the {{else}} sub-helper, allowing multiple statements to be chained together, should the initially targeted array or object be empty or not exist.

  • {{#each steps.1.attributes.data.array1}}{{this}}{{else each steps.1.attributes.data.array2}}{{this}}{{else}}No items found{{/each}}

To parse and fully convert stringified JSON into literal JSON, use the /#fn:parseJSON function helper. This will require an additional workflow step, such as "Transform Generic."

With

The {{#with}} block helper accepts an object or an array as an argument, and allows contained values to be locally referenced by key or index.

  • Given steps.1.attributes.data.hero = {firstName": "Peter", "lastName": "Parker"}
    {{#with steps.1.attributes.data.hero}}My name is {{firstName}} {{lastName}}{{/with}} resolves to the string "My name is Peter Parker"

  • Given steps.1.attributes.data.hero = ["Peter", "Parker"]
    {{#with steps.1.attributes.data.hero}}My name is {{0}} {{1}}{{/with}} resolves to the string "My name is Peter Parker"

As a block helper, {{#with}} has access to the {{else}} block, allowing multiple statements to be chained together, should the initial statement resolves to a null value.

  • {{#with steps.1.attributes.data.hero1}}{{firstName}} {{lastName}}{{else with steps.1.attributes.data.hero2}}{{firstName}} {{lastName}}{{else}}No heroes found{{/with}}

Lookup

The {{lookup}} helper retrieves the value of an attribute using its key name, making it useful for dynamically referencing object data. It accepts two parameters: an object, and a key that specifies the desired data within the object.

  • Given steps.1.attributes.data = {firstName": "Peter", "lastName": "Parker"}
    {{lookup steps.1.attributes.data 'firstName'}} resolves to the string "Peter"

Like all helper expressions, the lookup helper only outputs a string. If the value of the identified attribute is an array, its items will be concatenated into a single string, without array brackets. If the value is an object, it will be represented as the string "[object Object]".

To interpret arrays and objects as stringified JSON data, use the toJSON helper.

To JSON

The {{toJSON}} helper converts an object into a stringified JSON format, including escaped characters. This is useful when array data is missing standard brackets or when object data defaults to the string "[object Object]".

  • Given steps.1.attributes.data = {"hero": {firstName": "Peter", "lastName": "Parker"}, "team": ["Spiderman", "Daredevil"], {"identifier": "hero"}
    {{toJSON steps.1.attributes.data.team}} resolves to the stringified JSON "[\"Spiderman\",\"Daredevil\"]"

    {{toJSON (lookup steps.1.attributes.data steps.1.attributes.data.identifier)}} resolves to the stringified JSON "{\"firstName\":\"Peter\",\"lastName\":\"Parker\"}"

To parse and reference a specific value within stringified JSON, see the parseJSON helper.

To parse and fully convert stringified JSON into literal JSON, see /#fn:parseJSON. Making this conversion sequentially will require an additional workflow step, such as "Transform Generic."

Parse JSON

The /#fn:parseJSON function helper accepts stringified representations of JSON data and converts to an output of literal JSON data.

  • Given steps.1.attributes.data.stringifiedJSON = "{\"firstName\":\"Peter\",\"lastName\":\"Parker\"}"
    /#fn:parseJSON,steps.1.attributes.data.stringifiedJSON resolves to the object {"firstName": "Peter", "lastName": "Parker"}

To capture an output of stringified JSON data, see the {{toJSON}} helper.

The {{#parseJSON}} block helper similarly accepts stringified JSON data. However, this helper's functionality is more aligned with the {{#with}} helper, as it will only extract specific values by key or index.

  • Given steps.1.attributes.data.stringifiedHero = "{\"firstName\":\"Peter\",\"lastName\":\"Parker\"}"
    {{#parseJSON steps.1.attributes.data.stringifiedHero}}My name is {{firstName}} {{lastName}}{{/parseJSON}} resolves to the string "My name is Peter Parker"

  • Given steps.1.attributes.data.stringifiedHero = "[\"Peter\",\"Parker\"]"
    {{#parseJSON steps.1.attributes.data.stringifiedHero}}My name is {{0}} {{1}}{{/parseJSON}} resolves to the string "My name is Peter Parker"

Parse Int / Parse Float

The /#fn:parseInt function helper converts a stringified number value into a standard number-type integer value, while /#fn:parseFloat converts a stringified number value into a number-type value with any included decimals (also known as a "float").

Any string that begins with a non-numeric character will result in a number value of 0. Any stringified number with additional non-numeric characters will result in the number up to the first non-numeric character

  • Given steps.1.attributes.data.number = "10"
    /#fn:parseInt,steps.1.attributes.data.number resolves to the number value 10

  • Given steps.1.attributes.data.number = "10.90"
    /#fn:parseFloat,steps.1.attributes.data.number resolves to the number value 10.9

    /#fn:parseInt,steps.1.attributes.data.number resolves to the number value 10

  • Given steps.1.attributes.data.number = "10abc"
    /#fn:parseFloat,steps.1.attributes.data.number resolves to the number value 10

  • Given steps.1.attributes.data.number = "abc10"
    /#fn:parseInt,steps.1.attributes.data.number resolves to the number value 0

Parse Bool

The /#fn:parseBool helper converts a stringified boolean value (true or false) into a standard boolean value. Any unrecognized input will default to false.

  • Given steps.1.attributes.data.open = "true"
    /#fn:parseBool,steps.1.attributes.data.open resolves to the boolean value true

Transform

The /#fn:transform helper performs bulk updates to the names of object keys in an array of objects and returns the full array with the updated keys.

  • Given steps.1.message = [{"subject": "message a", "preview": "hello"}, {"subject": "message b", "preview": "goodbye"}]
    /#fn:transform,steps.1.messages,title=subject,body=preview resolves to the array [{"title": "message a", "body": "hello"}, {"title": "message b", "body": "goodbye"}]

Map 

Given an array of sequential objects, the /#fn:map function helper assembles the values of a specified recurring object key and outputs them into a unique array. For example, an agent can use this helper to take an array of customer objects and create a new array containing just the listed email addresses.

  • Given steps.1.attributes.data = {"customers": [{"name": "Agent A", "email": "email-a@example.com"}, {"name": "Agent B", "email": "email-b@example.com"}]}
    /#fn:map,steps.1.attributes.data.customers,email resolves to the array ["email-a@example.com", "email-b@example.com"]

In addition to arrays, this helper can be used on sequential objects with a repeated key attribute.

  • Given steps.1.attributes.data = {"firstAgent": {"name": "Agent A", "email": "email-a@example.com"},  "secondAgent": {"name": "Agent B", "email": "email-b@example.com"}}
    /#fn:map,steps.1.attributes.data,email resolves to the array ["email-a@example.com", "email-b@example.com"]

For sequential array values, the desired index can target the desired values from the array.

  • Given steps.1.attributes.data = {"firstAgent": ["Agent A", "email-a@example.com"], "secondAgent": ["Agent B", "email-b@example.com"]}
    /#fn:map,steps.1.attributes.data,1 resolves to the array ["email-a@example.com", "email-b@example.com"]

If a specific target is not defined, the entire array will be returned in full. Additionally, strings can be mapped to return an array of individual characters.

  • Given steps.1.name = "Bruce"
    /#fn:map,steps.1.name resolves to the array ["B", "r", "u", "c", "e"]

Included Resource Attribute

The /#fn:findIncludedResourceAttribute function helper takes an array of objects as an argument, and targets one if the objects from which to return a specified attribute value. The targeted object is identified as the first object that contains a match for a set of provided attribute values.

For example, in an array of message objects, this helper could return the channel used for a message containing a specified subject line, or it could return the subject line for a message by a specified direction and channel.

  • Given steps.1.messages = [{"subject": "message a", "direction": "in", "channel": "email"}, {"subject": "message b", "direction": "out", "channel": "email"}, {"subject": "message c", "direction": "in", "channel": "sms"}]
    /#fn:findIncludedResourceAttribute,steps.1.messages,subject=message a,channel resolves to the string "email"

    /#fn:findIncludedResourceAttribute,steps.1.messages,direction=in,channel=sms,subject resolves to the string "message c"

When matching a value to target an object, only string-type values can used for matching, although selecting nested child attributes via data path is supported. The output will always be the data type of the queried attribute.

  • Given steps.1.attributes.data = [{"operations": {"start": "combine", "end": "reduce"}, "numbers": [1, 3, 5]}]
    /#fn:findIncludedResourceAttribute,steps.1.attributes.data,operations.start=combine,numbers resolves to the array [1, 3, 5]

Related articles: