FLOWLOGIC
module /data-shaping-and-validation

unit U33 of 5

Arrays & nested reads

safe collection handling, empty is not an error

Real payloads are rarely flat. A webhook carries `line_items` as an array, an enrichment response nests `company.location.country`, and a CRM search returns a list you have to pick the right element from. Working with collections safely is mostly about never assuming an array has the element you want, and never assuming a nested path exists.

Reach for the right operation. `map` reshapes every element; `filter` drops the ones you do not want; `find` returns the first match or `undefined`, which you must handle. `reduce` is for collapsing a list to one value — a total, a lookup object — and is worth avoiding when a clearer `filter().map()` says the same thing. For nested reads, chain `?.` the whole way down: `resp?.company?.location?.country` yields `undefined` at the first missing link instead of throwing on the second.

Where it breaks: indexing straight into an array. `items[0].sku` throws the first time a payload arrives with an empty `items`, and it is the kind of payload that shows up on a Sunday. Check the length, or use `find` and handle the miss, and decide explicitly what an empty collection means — often it is a valid record that simply has nothing to process, not an error.

worked example

Reshaping an order payload whose line items may be absent, empty, or missing fields.

export const code = async (inputs) => {
  const order = inputs.order;

  // Default to [] so every operation below is safe on an absent or null field.
  const items = Array.isArray(order?.line_items) ? order.line_items : [];

  const billable = items
    .filter((i) => Number.isFinite(Number(i?.qty)) && Number(i.qty) > 0)
    .map((i) => ({
      sku: i?.sku ?? 'unknown',
      qty: Number(i.qty),
      unit: Number(i?.price ?? 0),
    }));

  return {
    country: order?.customer?.address?.country ?? null,   // safe the whole way down
    lineCount: billable.length,
    total: billable.reduce((sum, i) => sum + i.qty * i.unit, 0),
    // An empty order is a VALID record with nothing to bill, not a failure.
    empty: billable.length === 0,
  };
};

field checklist

common failure — items[0] on an empty order

A billing flow read `order.line_items[0].sku` to label each run. Most orders had items, so it worked for months — until a cancelled order arrived with an empty array and the step threw, failing the whole run and stopping the batch behind it. Default the array, check the length, and treat "no items" as a valid record with nothing to bill rather than an error.

check your understanding

This line must not throw when the payload has no line items at all. Which check belongs in the blank so the fallback is an empty array?

const items =(order?.line_items) ? order.line_items : [];

next unit opens once this is passed

sandbox validation

The check above confirms you followed the unit. Marking the module COMPLETED takes more: build the automation in your own engine and submit the exported flow and its run evidence, signed, to your unique validation URL. See the module page for that spec.