Understand Data Structures in n8n
Basics
- All data passed between nodes is an array of objects
- To manipulate data, n8n needs this data structure:
[items array: {json:obj}, {json:obj}, {json:obj}]
- But often our data will be in the format:
[items array: [ json array: {obj}, {obj}, {obj} ] ]
- Each n8n node runs its operations on each item in the array
- So in the first data structure it operates 3 times on {json:obj}
- But in the second data structure it operates just once on the json array.
Unbundling
When you have the second type of data structure, you need to:
1) First unbundle the json array into items
2) Then run operations on each individual item.
To do this, use a function node:
return items[0].json.map( item => ( { json : item } ));
Nested Items
Sometimes (e.g. with external APIs returning data in a different format), you will encounter nested items. This usually means the data we are interested in is its own object nested within the JSON response from the API.
Where "results" is the object/array of interest, we would modify our function above as so:
return items[0].json.results.map(item => ( { json : item } ));
Recap
- You always have an items array in every n8n node
- In the items array are one or more JSON object arrays
- Usually if there is just one JSON object in the items array, we will be interested in the objects within the JSON array.
- This is where unbundling as above is required.
- If there are multiple JSON objects in the items array, we are interested in unbundling the JSON object into separate items - using the function for nested items.
- When there are multiple items - that's ideal because it's what we usually want. It is the level n8n performs operations on.
Bonus
To bundle up data (e.g. when we want to export the output of our operations to another service):
1. Start by declaring: const = data
2. End with: return [ { json: {data} }];
3. Fill up the data constant as so:
const data = items.map ( items => 'Name: ${item.json.name}, URL: ${item.json.url}').toString();