Unwind Operator

Introduction

Data often has nested values. But how can you separate those values? That's where the Unwind operator comes in. The Unwind operator raises the values in a nested array to the next level.

For example, start with the following array:

Copy
[
  {
    "keyA": "A",
    "keyB": "B",
    "keyC": [
      "C"
    ]
  }
]

Notice how the key "keyC" has an array as its value. That is, a nested array. If you use the Unwind operator, the value in that nested array, "C" moves to the same level of the data structure as the values "A" and "B". The final array looks like this:

Copy
[
  {
    "keyA": "A",
    "keyB": "B",
    "keyC": "C"
  }
]

Now, all three values are at the same level of the data structure.

Look for the Unwind operator in the Table group on the left of the Data Workflow canvas.

What You'll Learn

In this article, you'll learn:

Info Window Settings

The Unwind operator looks like this, along with its Info window:

And here's a breakdown of each setting in the Info window:

Setting

Description

Label

Sets the label for your operator. The label you enter here shows beneath your operator on your Data Workflow canvas.

This field is optional, but set a label if you use more than one of the same operator type. A label helps you identify your operators without opening any Info windows.

Keep Embedding

Specifies whether to keep the original, nested key in the final, unwound array. When set to Yes, the value(s) in the nested array displays in the unwound array paired with the original nested key. When set to No, the values in the nested array separate out. Once separated, they index, character by character, into the higher level array.

Note: The Keep Embedding setting works somewhat differently when unwinding an array of objects. To see examples of how Keep Embedding works with nested objects vs arrays of values, check out the How Unwind Works on Different Arrays section below.

Unwind Key

Specifies which key contains the nested array you want to bring to a higher level of the data structure. Enter _arg in this field to sort by the value coming into the operator's argument port.

For example, if you have the following array: [{"keyA":"A", "keyB":"B", "keyC":["C"]}].

You'll unwind on "keyC" to bring the value in the nested "keyC" array to the same level as the original array. The final, unwound array looks like this: [{"keyA":"A", "keyB":"B", "keyC":"C"}].

Adding and Configuring the Unwind Operator to Filter and Get Values

Next, let's see the Unwind operator in action. In this use case, you learn how to use the Unwind operator in a pretty common scenario. The Address component stores complete information about each address. Sometimes, you need to extract a few specific values and store them elsewhere. The Unwind operator extracts values from the Address component's "address" data object. In essence, Unwind helps you pull specific values from the address data object.

When you enter an address with an Address component, Unqork talks to the Google Maps API (application programming interface). The Google Maps API returns information about the address you entered. The data object of the Address component stores this information.

The "address" data object includes some commonly-referenced fields, like city or zip. More specific details are also available. For example, the two-letter state abbreviation, or the township. These specific details exist in the "address_components" array in the "address" data object. But, each row of the array also has another nested array called "types". This "types" array indicates which category of address information is in that row. For example, the value in the types array can be "street_number" or "postal_code_suffix".

Unwinding the "types" key brings this category value to the same level as the address information itself.

After you use Unwind, you use Filter and Get operators in this use case. Those operators pull the specific address information. The Filter operator filters information from the "address_components" array by a particular "types" value. For example, you can filter out the row with "types":"street_number". Then, the Get operator extracts, or gets, the street number.

The completed use case looks like this in the Module Builder:

The complete use case works like this in Express View, including the final values in the DevTools Console:

What You'll Need

For this use case, you'll need:

  • 1 Address component

  • 1 Button component

  • 1 Data Workflow component

To configure your Data Workflow, you'll need:

  • 1 Input operator

  • 3 Get operators

  • 1 Unwind operator

  • 2 Filter operators

  • 4 Console operators

Configure the Address Component

Add an Address component to get an "address" data object for your Data Workflow.

1. Drag and drop an Address component onto your canvas.
2. Enter Address in the Label.
3. Enter address in the Property Name.
4. Select Street, Street2, City, State, Zip, and Country.
5. Click Save.

Configure the Data Workflow Component

With the Address component configured, use your Unwind operator to pull certain values. In this use case, your Data Workflow pulls two values: the two-letter state and country abbreviations.

1. Drag and drop a Data Workflow component onto your canvas, placing it below the Address component.
2. Enter dwfUnwind in the Label and Property Name.
3. Select Manual from the Trigger Type.

Configure the Input Operator

Connect your address component to the Data Workflow with an Input operator.

1. Drag and drop an Input operator onto your Data Workflow canvas.
2. Configure the operator's Info window as follows:

Setting

Value

Category

Input

Component

address

Required

Yes

Source

Default

Configure the First Get Operator

Connect this Get operator to the "address_components" array in the "address" data object.

1. Drag and drop a Get operator onto your Data Workflow canvas.
2. Configure the operator's Info window as follows:

Setting

Value

Category

Get

Label

Get address_components array

Path

address_components

3. Connect the output port (right) of the Input operator to the input port (left) of the Get operator.

Configure the Unwind Operator

Use the Unwind operator to unwind on the "types" key. This brings the values in the nested "types" array to the same level as the information in each row of the "address_components" array.

1. Drag and drop an Unwind operator onto your Data Workflow canvas.
2. Configure the operator's Info window as follows:

Setting

Value

Category

Unwind

Label

Unwind on types

Keep Embedding

Yes

Unwind Key

types

3. Connect the output port (right) of the Get operator to the input port (left) of the Unwind operator.

Configure the Filter Operators

Use two Filter operators to isolate the values you want. Each Filter operator filters according to a specific "types" value. This is possible because, after unwinding, there's now a "types" value in each row of the array. To figure out which "types" value to use in the expression, look at the original "types" array. For example, the "types" value "administrative_area_level_1" corresponds to the State row of information.

1. Drag and drop two Filter operators onto the Data Workflow canvas.
2. Configure the first Filter operator's Info window as follows:

Setting

Value

Category

Filter

Label

Filter State

Do Not Sanitize Formula

 

Expression

types="administrative_area_level_1"

3. Connect the output port (right) of the Unwind operator to the input port (left) of this first Filter operator.
4. Configure the second Filter operator's Info window as follows:

Setting

Value

Category

Filter

Label

Filter Country

Do Not Sanitize Formula

 

Expression

types="country"

5. Connect the output port (right) of the Unwind operator to the input port (left) of this second Filter operator.

Configure the Second and Third Get Operators

Use Get operators to pull a specific value from each filtered-out row. Each row contains both a "long_name" and "short_name" value. For example, if the State "long_name" value is New York, then the "short_name" is NY. For this use case, pull the "short_name" value for State and Country.

1. Drag and drop two more Get operators onto the Data Workflow canvas.
2. Configure the second Get operator's Info window as follows:

Setting

Value

Category

Get

Label

Get State short_name

Path

[0].short_name

3. Connect the upper output port (right) of the Filter StateFilter operator to the input port (left) of this second Get operator.
4. Configure the third Get operator's Info window as follows:

Setting

Value

Category

Get

Label

Get Country short_name

Path

[0].short_name

5. Connect the upper output port (right) of the Filter CountryFilter operator to the input port (left) of this third Get operator.

Configure the Four Console Operators

Add four Console operators to see the outcome of each step in the process. Connect one Console operator to the first Get operator to see the "address_components" array before unwinding. Then, connect another to the Unwind operator to see the "address_components" array after unwinding. And connect two to the second and third Get operators. These display exactly what values the Data Workflow gets from the address data object.

Notice that the second and third Get operators only output to Console operators. You might also want to use dedicated Output operators when you create applications. Then, you can connect those Output operators to Hidden components. This lets you store the final values for reference elsewhere in your application.

1. Drag and drop 4 Console operators onto your Data Workflow canvas.
2. Configure the first Console operator's Info window as follows:

Setting

Value

Category

Console

Label

Before Unwind

3. Connect the output port (right) of the Get address_components arrayGet operator to the input port (left) of this first Console operator.
4. Configure the second Console operator's Info window as follows:

Setting

Value

Category

Console

Label

After Unwind

5. Connect the output port (right) of the Unwind operator to the input port (left) of this second Console operator.
6. Configure the third Console operator's Info window as follows:

Setting

Value

Category

Console

Label

State short_name

7. Connect the output port (right) of the Get State short_nameGet operator to the input port (left) of this third Console operator.
8. Configure the fourth Console operator's Info window as follows:

Setting

Value

Category

Console

Label

Country short_name

9. Connect the output port (right) of the Get Country short_nameGet operator to the input port (left) of this fourth Console operator.
10. Click Save.

Configure the Button Component

Create a button to click in Express View that triggers your Data Workflow.

1. Drag and drop a Button component onto your canvas, placing it below the Data Workflow.
2. Enter btnRunDWF in the Property ID.
3. Enter Run Unwind in the Label Text.
4. Select Event from the Button Action Type.
5. Enter dwfUnwind in the Trigger on Click field.

6. Click Save.
7. Save your module.

Now, test your Data Workflow. Preview your module in Express View and open the DevTools Console. Enter an address in your Address field, then click the Run Unwind button. Look at the DevTools Console display. It looks something like this:

Notice that there are more rows in the After Unwind array than in the Before Unwind array. Some rows of the original array had two "types" values. For example, look at row two of the Before array ("Edgewater"). Its "types" value is an array with two rows. Then, they separated into row two and row three in the After array. That way, each row of the After array only has a single "types" value.

NOTE  The process in this use case is an Unqork snippet. The Unwind-Filter-Get Data Workflow is the basis of the Address Parsing snippet. Look at this snippet and explore its dwfPopulateAddress Data Workflow.

How Unwind Works on Different Arrays

Next, you'll explore how the Unwind operator works on different types of arrays. Arrays of values aren't the only types of arrays. Sometimes, you'll work with an array of objects instead. Let's learn how the Unwind operator works on a few sample arrays, like a nested array of:

  • One value.

  • Multiple values.

  • Objects.

You'll also see the effect of setting Keep Embedding to either Yes or No. So, take a moment to explore the following tables and compare and contrast each one. If you don't fully understand how to read the JSON below, don't worry. Recognizing objects, arrays becomes easier over time. These tables help you understand how Unwind works in different contexts.

Array with One Value

Use the following sample array:

Copy
[
  {
    "keyA": "A",
    "keyB": "B",
    "keyCDE": [
      "CDE"
    ]
  }
]

The value of "keyCDE" is an array with one value. So, unwind on keyCDE to un-nest the array.

This table displays the outcome of unwinding on the "keyCDE" key. In the first column, the Keep Embedding setting is set to Yes. In the second column, it's set Keep Embedding to No.

Unwound on keyCDE, Keep Embedding set to Yes

Unwound on keyCDE, Keep Embedding set to No

Copy
[
  {
    "keyA": "A",
    "keyB": "B",
    "keyCDE": "CDE"
  }
]
Copy
[
  {
    "0": "C",
    "1": "D",
    "2": "E",
    "keyA": "A",
    "keyB": "B"
  }
]

Array with Multiple Values

Next, another sample array. This time, though, the array has multiple values.

Copy
[
  {
    "keyA": "A",
    "keyB": "B",
    "keyADG": [
      "ABC",
      "DEF",
      "GHI"
    ]
  }
]

The value of "keyADG" is a nested array with three values. So, unwind on keyADG and check the results in the table below. Like before, the first column displays the effect of setting Keep Embedding to Yes. The second column displays the outcome of setting Keep Embedding to No.

Unwound on keyADG, Keep Embedding set to Yes

Unwound on keyADG, Keep Embedding set to No

Copy
[
  {
    "keyA": "A",
    "keyB": "B",
    "keyADG": "ABC"
  },
  {
    "keyA": "A",
    "keyB": "B",
    "keyADG": "DEF"
  },
  {
    "keyA": "A",
    "keyB": "B",
    "keyADG": "GHI"
  }
]
Copy
[
  {
    "0": "A",
    "1": "B",
    "2": "C",
    "keyA": "A",
    "keyB": "B"
  },
  {
    "0": "D",
    "1": "E",
    "2": "F",
    "keyA": "A",
    "keyB": "B"
  },
  {
    "0": "G",
    "1": "H",
    "2": "I",
    "keyA": "A",
    "keyB": "B"
  }
]

So, with Keep Embedding set to Yes, the outcome displays three objects, and each object has a "keyADG" key with a different value. Each "keyADG" value comes from the original nested array. So, if the original nested array has five values, the outcome displays five objects.

With Keep Embedding set to No, the outcome displays three objects again. But, this time there's no "keyADG" key in each object. Instead, each value from the original nested array gets separated, character by character, into one of the objects.

Array of Objects

Now, look at how the Unwind operator works on an array of objects. Here's the sample array:

Copy
[
  {
    "keyA": "A",
    "keyB": "B",
    "keyADG": [
      {
        "value": "ABC"
      },
      {
        "value": "DEF"
      },
      {
        "value": "GHI"
      }
    ]
  }
]

The value of "keyADG" is an array of three objects: [{"value":"ABC"}, {"value":"DEF"}, {"value":"GHI"}]. So, see what happens when you unwind on keyADG. Like before, the table's left column displays the effect of setting Keep Embedding to Yes. And the right column displays the effect of setting Keep Embedding to No.

Unwound on keyADG, Keep Embedding set to Yes

Unwound on keyADG, Keep Embedding set to No

Copy
[
  {
    "keyA": "A",
    "keyB": "B",
    "keyADG": {
      "value": "ABC"
    }
  },
  {
    "keyA": "A",
    "keyB": "B",
    "keyADG": {
      "value": "DEF"
    }
  },
  {
    "keyA": "A",
    "keyB": "B",
    "keyADG": {
      "value": "GHI"
    }
  }
]
Copy
[
  {
    "keyA": "A",
    "keyB": "B",
    "value": "ABC"
  },
  {
    "keyA": "A",
    "keyB": "B",
    "value": "DEF"
  },
  {
    "keyA": "A",
    "keyB": "B",
    "value": "GHI"
  }
]

The outcome displays an array of three objects whether you set Keep Embedding to Yes or No. But, notice how the "keyADG" key disappears when you set Keep Embedding to No.

When you set Keep Embedding to Yes, each object displays a "keyADG" key/value pair. The value is one of the objects in the original nested array.

When you set Keep Embedding to No, each object loses the "keyADG" key/value pair. Instead, contents of the objects in the original nested array move up a level to replace the "keyADG" key/value pair.

Changing a Unwind Operator's Settings

You can revisit and make changes to this operator.

1. Click the Data Workflow component.

A 5-button toolbar displays above the component on hover-over.

2. Click the (Settings) button to open the Data Workflow canvas.
3. Click the operator to open its Info Window.
4. Make changes to the operator's settings as needed.
5. Click Save.
6. Save your module.

Copying an Unwind Operator

You can make a copy of your operator using familiar keyboard settings. You can copy and paste an exact copy of your operator, matching all settings.

1. Hover over the Data Workflow component.

A 5-button toolbar displays above the component on hover-over.

2. Click the (Settings) button to open the Data Workflow canvas.
3. Click the operator you want to duplicate.
4. On your keyboard, press Command + C (Mac OS) or Ctrl + C (Windows/Linux) to copy the operator.

TIP  You can copy more than one operator at a time. Hold Command or Ctrl on your keyboard and click all the operators you want to copy. Follow the rest of the steps as usual.

5. On your keyboard, press Command + V (Mac OS) or Ctrl + V (Windows/Linux) to paste the copied operator(s) to the Data Workflow canvas.
6. Click Save.
7. Save your module.

TIP  Did you know you can copy an operator and paste it into a different Data Workflow? You'll use the same steps outlined above.

Removing an Unwind Operator

Lastly, you can delete this operator from your Data Workflow canvas. You can also use these same steps to delete a connection between two operators.

1. Hover over the Data Workflow component.

A 5-button toolbar displays above the component on hover-over.

2. Click the (Settings) button to open the Data Workflow canvas.
3. Click the operator you want to delete.
4. On your keyboard, press Delete.

NOTE  Once you delete this operator, make sure to connect your remaining operators. If your Data Workflow path doesn't end with an Output or Console operator, your Data Workflow won't work. So, once you delete an operator, make sure to update any remaining paths to end at an Output or Console operator.

5. Click Save.
6. Save your module.

Lab

You can find the completed Unwind Operator lab here: https://training.unqork.io/#/form/5f6c9b0585a56f024db5a76a/edit.