Make data handling

Make bundles and arrays: six worked examples

Check the shape of your data before adding another module. A bundle is one package passed between modules. An array is a list inside a package. Confusing the two can turn one intended message into several.

These examples use made-up data and show expected results. They have not been run in connected accounts. Test your version before using it for real work.

01

Look at the output before adding another module

Three emails may arrive as three bundles. One email may contain an array of three attachments. The first case already has separate records. The second has a list inside one record.

Open the output bubble above the module and inspect its bundles and fields. Make's operations guide explains that view. If a search already emits one bundle per result, the next action normally handles each bundle separately. Add an Iterator when an array needs that treatment, not simply because several records exist. See the module types.

These six exercises use made-up data and expected outputs. They were not run in a connected customer scenario. Use a separate scenario without live email, payment or record-creation actions. A temporary Tools > Set variable lets you inspect the final value. Write down the expected counts before running your own test.

02

Example 1: split one order's lines into two bundles

Add JSON > Parse JSON and put this object in its JSON string field. Generate the data structure from the sample, or run that module alone so the later mapper knows its fields.

{
  "orderId": "ORD-41",
  "lines": [
    {"sku": "BEACON-A", "quantity": 2},
    {"sku": "HARBOR-B", "quantity": 1}
  ]
}

Expect one Parse JSON output bundle. It contains orderId and an array named lines with two items. Add an Iterator and map the whole lines[] array into its Array field. Do not map just the first SKU.

Iterator output bundle 1:
{"sku": "BEACON-A", "quantity": 2}

Iterator output bundle 2:
{"sku": "HARBOR-B", "quantity": 1}

After the Iterator, add Tools > Set variable. Name the variable currentSku and map the Iterator's current sku as its value. Expect two operations at that variable module, containing BEACON-A and HARBOR-B. An email action in that position could also run twice.

Check this chain: one object, one array with two items, two Iterator output bundles, two final variable operations. If the Iterator produces one result, look for an index that selected only one element. If both final values are BEACON-A, check whether the variable maps the original array's first item instead of the Iterator's current item.

If the mapper shows only bundle position or count fields, define the input structure or run Parse JSON alone with the sample first. The Iterator guide covers missing field information, and array mapping explains element selection.

Keep the outer braces in this exercise. A root JSON array behaves differently: Parse JSON can already produce separate bundles for its items. The JSON module documentation describes that difference. Do not change the input shape and assume the expected counts still apply.

03

Example 2: produce one array for the whole order

Reuse Example 1's Parse JSON and Iterator. Remove the final variable and add an Array aggregator directly after the Iterator. Choose that Iterator as Source module. Set the target structure to Custom, select sku and quantity as aggregated fields, and leave Group by empty.

Expect one aggregator output bundle containing this array:

[
  {"sku": "BEACON-A", "quantity": 2},
  {"sku": "HARBOR-B", "quantity": 1}
]

Add a new temporary Set variable after the aggregator. Map the whole aggregated array into its value. It should receive one list for this order, not one call for each line. This is the arrangement to consider when a later document or handover step needs all the rows together.

Check the grey aggregation area after selecting the source. The aggregator collects bundles within the selected source operation. It does not store items between separate scenario runs. Choosing an inner source that executes repeatedly can produce several small groups instead of the intended larger result. See aggregation source and scope.

Inspect both objects in the resulting array. Each must include its quantity as well as its SKU. Fields inside the aggregation area do not automatically remain available afterward; select the values the next step needs. Fields outside that area follow their normal mapping scope.

For this sample, orderId comes from Parse JSON before the Iterator. Keep it available for the handover. If a later design moves it inside the aggregation area, carry it into the aggregated structure explicitly. Missing orderId is a lost field, not an empty order. Compare the expected two lines with the actual array length before connecting the next app.

04

Example 3: make one result per delivery team

Replace the input with this object and update the Parse JSON data structure. Map items[] into the Iterator. Use that Iterator as the Array aggregator's source.

{
  "batchId": "BATCH-6",
  "items": [
    {"workId": "W-1", "team": "North", "hours": 2},
    {"workId": "W-2", "team": "South", "hours": 4},
    {"workId": "W-3", "team": "North", "hours": 3}
  ]
}

Select workId, team and hours as aggregated fields. Map the current item's team into Group by. Expect two output bundles, one for each distinct group key:

Key North:
[
  {"workId": "W-1", "team": "North", "hours": 2},
  {"workId": "W-3", "team": "North", "hours": 3}
]

Key South:
[
  {"workId": "W-2", "team": "South", "hours": 4}
]

The North array contains W-1 and W-3; South contains W-2. Grouping keeps the rows. It does not calculate total hours. If the next action creates a handover, this setup would create two handovers, one per output group. The Group by setting controls that grouping.

Check membership as well as count. Two output bundles are not enough proof if W-3 is in the wrong team. Do not depend on North appearing before South; identify a group by its key.

Add a fourth test item with no team. Decide whether to reject it or route it for review before grouping. Check inconsistent values such as North and NORTH as well. A missing or inconsistent business label needs a rule; do not hide it inside an unnamed group.

Run a second batch separately and expect its own results. An aggregator is not storage for combining work across runs. If a group will become a recipient or destination, look the key up in an approved list. A label such as North is not an email address, and grouping does not verify who should receive the records.

05

Example 4: decide what happens when every line is filtered out

Return to Example 1's two lines. Put a filter between the Iterator and Array aggregator: quantity is greater than 9. Keep the source set to the Iterator. It has run and produced two candidates, but neither passes the filter.

Input quantities: 2, 1
Filter: quantity > 9
Bundles reaching aggregator: 0

Stop processing after an empty aggregation = disabled:
Expected aggregated array: []

Stop processing after an empty aggregation = enabled:
Expected: no aggregator output bundle

A filter passes matching bundles onward. The empty aggregation setting controls what this aggregator does when none reach it.

Test both settings using the temporary final variable. With stopping disabled, inspect an empty array. With stopping enabled, expect the final variable not to run. Choose deliberately: a report may need to say “no matching work,” while an alert may have nothing to send.

Trace the counts before deciding this is correct: Parse JSON produced one bundle, the Iterator produced two, the filter accepted zero, and the aggregator either continued with an empty array or stopped. If Parse JSON failed, this was not a successful zero-match test. If the Iterator never ran, do not use the aggregator's setting as proof the source was checked.

Now remove quantity from one input item. Treat that as invalid data, not evidence that its quantity is zero. Define how required fields are checked before the business filter. If rejected lines need follow-up, create that review route deliberately; a filter does not save rejected items for you.

When replacing the sample with a search module, check its query, limits and paging. No returned rows, a failed query and an incomplete set of pages are three different outcomes.

06

Example 5: make a short SKU list without splitting the array

Use Example 1's input again. This time the result only needs to be a short text list of product codes. No app action needs to run separately for each line, so leave out the Iterator and Aggregator.

Place Tools > Set variable after Parse JSON and name it skuList. In its value field, build a map function using the whole lines array token as the first argument and the raw key sku as the second. Wrap that result in join, with a comma followed by a space as the separator. Select the array token from your own module; do not type the label lines[] as plain text.

Input lines:
[
  {"sku": "BEACON-A", "quantity": 2},
  {"sku": "HARBOR-B", "quantity": 1}
]

After map extracts sku:
["BEACON-A", "HARBOR-B"]

After join uses comma and space:
BEACON-A, HARBOR-B

Make's array functions define map as extracting values from a complex array and join as turning an array into text. Here the array already exists inside one bundle. Expect one Parse JSON bundle and one variable operation with one string.

If the result looks like objects instead of product codes, inspect the map result before join. If it contains only BEACON-A, check for a first-item selection. If a SKU is missing, decide whether to reject that line before building the text. Do not assume joining validates required fields.

Use this method for a readable list, not a file format that needs escaped commas or quoted fields. It also does not combine separate incoming bundles. If the previous search produces one bundle per item, use aggregation to combine those records first.

07

Example 6: make one summary with a row for each line

Start from Example 1's Parse JSON and Iterator. Remove the temporary variable, then add Tools > Text aggregator. Choose the Iterator as Source module. Leave grouping empty and select New row as the row separator.

In Text, insert the current Iterator's sku token, type a colon and a space, then insert its quantity token. This builds a line such as BEACON-A: 2 from each bundle. Add a temporary Set variable afterward and map the aggregator's text output into it.

Iterator supplies:
{"sku": "BEACON-A", "quantity": 2}
{"sku": "HARBOR-B", "quantity": 1}

Expected single text result:
BEACON-A: 2
HARBOR-B: 1

Expected final variable operations: 1

The Make Academy Text aggregator guide documents the source, mapped text and row separator. The separator belongs between records. Putting a line break inside the template as well can leave unwanted blank rows.

Check that the source is still the Iterator and that both tokens come from its current item. Two identical lines often point to a fixed sample value or the original array's first item. Two separate summaries point to the grouping or source scope. Compare the aggregator's actual input and output before changing the final message step.

This example produces plain text. If an eventual destination expects HTML or another format, format and escape values for that destination instead of assuming line breaks will display the same way. Keep the practice run as a variable so no message is sent. Once the content is correct, connect an approved output and check its count separately.

08

Check counts and costs at each boundary

Keep a count sheet next to the scenario. For these samples, the expected boundaries are:

ExampleAfter Parse JSONIterator outputsFinal result
1. Split1 bundle22 variable operations
2. Combine1 bundle21 array with 2 items
3. Group1 bundle32 groups containing 2 and 1 items
4. Filter1 bundle2Empty array or no output, by setting
5. Join1 bundleNone used1 text value
6. Text summary1 bundle21 text value with 2 rows

These are data counts, not a credit estimate. Splitting items can multiply later operations. Credits are Make's current billing unit, and some features have different rates. Check current pricing and the run's operation and credit details.

Before handover, test one item, several items, an empty array and a missing field. Keep orders and batches separate. Confirm the next module needs text, an array or one object, and check required fields after aggregation. Save the sample input, expected counts and chosen empty-result behavior with the scenario. If the counts still do not line up, share the input and the result you need.

09

Sources

Primary documentation checked September 26, 2026. Inspect your module's actual input and output when trying these exercises.

Need help with this in your business?

Tell Felipe which tools you use, what keeps going wrong and what you want to improve. We can use a free 20-minute call to discuss a useful first project.

Prepare a project brief

Prefer email? felipe@getquintera.com. No booking, purchase or automatic submission.