Elke n8n workflow draait om data. Je haalt het op uit een API, bewerkt het, en stuurt het naar een andere service. Maar die data komt bijna nooit in het formaat dat je nodig hebt. Velden hebben verkeerde namen, arrays moeten gefilterd, objecten samengevoegd. Data transformatie is de vaardigheid die het verschil maakt tussen een fragiele workflow en een robuust automatiseringssysteem.
Wat je leert in deze gids:
- Hoe data stroomt in n8n: items, JSON en binary data
- Expressions syntax met {{ }}, $json, $node, $input
- Alle ingebouwde array functies (pluck, renameKeys, chunk, unique...)
- Object functies (hasField, isEmpty, keys, values...)
- String conversie functies (extractDomain, toNumber, toBoolean...)
- JMESPath voor complexe JSON queries
- Code Node vs Expressions: wanneer gebruik je wat?
- De AI Transform node voor natural language transformatie
- 10+ praktische voorbeelden die je direct kunt toepassen
Hoe Data Stroomt in n8n
Voordat je data kunt transformeren, moet je begrijpen hoe n8n data structureert. Elk stuk data dat tussen nodes stroomt volgt een vast formaat.
Het Item-Model
Alle data in n8n is een array van items. Elk item is een object met twee mogelijke properties:
// Zo ziet n8n data er intern uit
[
{
"json": {
"name": "Jan Jansen",
"email": "jan@bedrijf.nl",
"leeftijd": 34
},
"binary": {
"foto": {
"mimeType": "image/png",
"data": "base64string...",
"fileName": "profielfoto.png"
}
}
},
{
"json": {
"name": "Piet de Vries",
"email": "piet@bedrijf.nl",
"leeftijd": 28
}
}
]
json
Gestructureerde key-value data. Dit is wat je ziet in het output-panel en opvraagt met $json.veldnaam. Elk item moet een json property hebben.
binary
Bestandsdata: afbeeldingen, PDF's, CSV's. Optioneel per item. Gebruik de Convert to File / Extract From File nodes om hiermee te werken.
items[]
Data is altijd een array. Eén API response met 50 resultaten = 50 items. Nodes verwerken items automatisch één voor één.
In de Code node voegt n8n automatisch de json wrapper toe als je die weglaat (sinds versie 0.166.0). Maar in expressions werk je altijd direct met de json-inhoud via $json.
Expressions: De {{ }} Syntax
Expressions zijn de snelste manier om data te transformeren zonder een Code node te openen. Ze leven binnen dubbele accolades {{ }} en worden door n8n geëvalueerd op het moment van uitvoering.
Kernsyntax en Variabelen
// Toegang tot het huidige item
{{ $json.name }} // "Jan Jansen"
{{ $json.address.city }} // Geneste property
{{ $json.tags[0] }} // Eerste element van array
// Toegang tot data van een specifieke node
{{ $node["HTTP Request"].json.data }} // Output van een andere node
{{ $('HTTP Request').item.json.data }} // Alternatieve syntax (v1.x)
// Input helpers
{{ $input.first().json.id }} // Eerste item van input
{{ $input.last().json.id }} // Laatste item van input
{{ $input.all() }} // Alle input items (array)
{{ $input.item.json.name }} // Huidig item
// Workflow metadata
{{ $workflow.id }} // Workflow ID
{{ $workflow.name }} // Workflow naam
{{ $execution.id }} // Executie ID
{{ $now }} // Huidig tijdstip (Luxon DateTime)
{{ $today }} // Vandaag 00:00 (Luxon DateTime)
{{ $itemIndex }} // Index van huidig item (0-based)
{{ $env.MY_API_KEY }} // Environment variabele
Beperkingen van Expressions
Expressions moeten op één regel passen. Je kunt geen functies definiëren, geen multi-line code schrijven, en geen loops gebruiken. Heb je dat nodig? Gebruik dan de Code node.
Array Functies: De Complete Referentie
n8n biedt een uitgebreide set ingebouwde array functies die je direct in expressions kunt gebruiken. Dit zijn geen standaard JavaScript methoden maar custom n8n functies, speciaal ontworpen voor data transformatie in workflows.
| Functie | Beschrijving | Voorbeeld | Resultaat |
|---|---|---|---|
| .pluck(key) | Haalt één veld uit elk object in de array | {{ $json.users.pluck('name') }} | ["Jan", "Piet", "Klaas"] |
| .unique() | Verwijdert duplicaten uit de array | {{ [1, 2, 2, 3].unique() }} | [1, 2, 3] |
| .compact() | Verwijdert null, undefined en lege strings | {{ [1, null, "", 3].compact() }} | [1, 3] |
| .chunk(size) | Splitst de array in groepen van size | {{ [1,2,3,4,5].chunk(2) }} | [[1,2], [3,4], [5]] |
| .renameKeys(from, to) | Hernoemt keys in alle objecten in de array | {{ $json.items.renameKeys('naam', 'name') }} | [{name: "Jan"}, ...] |
| .randomItem() | Geeft een willekeurig element terug | {{ ["a", "b", "c"].randomItem() }} | "b" (willekeurig) |
| .union(otherArray) | Combineert twee arrays en verwijdert duplicaten | {{ [1,2].union([2,3]) }} | [1, 2, 3] |
| .difference(otherArray) | Elementen in base array die niet in other staan | {{ [1,2,3].difference([2]) }} | [1, 3] |
| .intersection(otherArray) | Elementen die in beide arrays voorkomen | {{ [1,2,3].intersection([2,3,4]) }} | [2, 3] |
| .sum() | Telt alle getallen in de array op | {{ [10, 20, 30].sum() }} | 60 |
| .average() | Berekent het gemiddelde | {{ [10, 20, 30].average() }} | 20 |
| .min() / .max() | Kleinste / grootste getal in de array | {{ [5, 2, 8].max() }} | 8 |
| .append(element) | Voegt element toe en retourneert de array | {{ [1, 2].append(3) }} | [1, 2, 3] |
| .smartJoin() | Combineert array van objecten tot één object | {{ [{a:1},{b:2}].smartJoin() }} | {a: 1, b: 2} |
| .toJsonString() | Converteert array naar JSON string | {{ [1, 2].toJsonString() }} | "[1,2]" |
Naast deze custom functies werken ook de standaard JavaScript array methoden: .filter(), .find(), .sort(), .reduce(), .indexOf(), .slice(), .join() en .concat().
Array Functies in de Praktijk
// Voorbeeld 1: Alle e-mailadressen uit een lijst contacten halen
{{ $json.contacts.pluck('email') }}
// ["jan@test.nl", "piet@test.nl", "klaas@test.nl"]
// Voorbeeld 2: Duplicaten verwijderen en lege waarden opruimen
{{ $json.tags.unique().compact() }}
// ["marketing", "sales", "support"] (zonder dubbelen en nulls)
// Voorbeeld 3: Items in batches van 10 splitsen voor API rate limits
{{ $json.allRecords.chunk(10) }}
// [[record1..10], [record11..20], ...]
// Voorbeeld 4: Keys hernoemen van Nederlands naar Engels
{{ $json.klanten.renameKeys('naam', 'name', 'adres', 'address') }}
// [{name: "Jan", address: "Keizersgracht 1"}, ...]
// Voorbeeld 5: Totale omzet berekenen
{{ $json.orders.pluck('amount').sum() }}
// 15340.50
// Voorbeeld 6: Vind items die in lijst A zitten maar niet in lijst B
{{ $json.allProducts.pluck('sku').difference($json.activeProducts.pluck('sku')) }}
// ["SKU-003", "SKU-007"] — discontinued producten
Object Functies: De Complete Referentie
Net als voor arrays heeft n8n custom functies voor het werken met objecten. Handig voor het valideren, filteren en transformeren van key-value data.
| Functie | Beschrijving | Voorbeeld | Resultaat |
|---|---|---|---|
| .hasField(name) | Checkt of een veld bestaat in het object | {{ $json.hasField('email') }} | true |
| .isEmpty() | True als object geen keys heeft of null is | {{ $json.metadata.isEmpty() }} | true/false |
| .isNotEmpty() | True als object minstens één key heeft | {{ $json.data.isNotEmpty() }} | true/false |
| .keepFieldsContaining(val) | Houdt alleen velden met waarden die val bevatten | {{ $json.keepFieldsContaining('test') }} | Object met matching velden |
| Object.keys() | Geeft alle keys als array (standaard JS) | {{ Object.keys($json) }} | ["name", "email", "age"] |
| Object.values() | Geeft alle waarden als array (standaard JS) | {{ Object.values($json) }} | ["Jan", "jan@test.nl", 34] |
| Object.entries() | Geeft key-value paren als array van arrays | {{ Object.entries($json) }} | [["name","Jan"], ...] |
| Object.assign() | Merge twee objecten samen (standaard JS) | {{ Object.assign({}, $json, {extra: true}) }} | Gecombineerd object |
Object Functies in de Praktijk
// Voorbeeld 1: Controleer of een verplicht veld aanwezig is
{{ $json.hasField('email') ? $json.email : 'geen email opgegeven' }}
// Voorbeeld 2: Voorkom errors bij lege objecten
{{ $json.response.isEmpty() ? 'Geen data ontvangen' : $json.response.naam }}
// Voorbeeld 3: Tel het aantal velden in een object
{{ Object.keys($json.formData).length }}
// 12
// Voorbeeld 4: Filter een object — houd alleen velden met "test" in de waarde
{{ $json.keepFieldsContaining('@gmail.com') }}
// {email: "jan@gmail.com", backup_email: "jan2@gmail.com"}
// Voorbeeld 5: Merge twee objecten
{{ Object.assign({}, $json, { verwerkt: true, timestamp: $now.toISO() }) }}
// Oorspronkelijk object + verwerkt + timestamp
String Functies voor Type Conversie
Data komt vaak als string binnen, ook als het eigenlijk een getal, boolean of datum is. n8n biedt conversie-functies die dit eenvoudig oplossen.
| Functie | Beschrijving | Voorbeeld | Resultaat |
|---|---|---|---|
| .extractDomain() | Haalt het domein uit een e-mail of URL | {{ "jan@bedrijf.nl".extractDomain() }} | "bedrijf.nl" |
| .toNumber() | Converteert string naar getal | {{ "42.5".toNumber() }} | 42.5 |
| .toBoolean() | Converteert string naar boolean. "0", "false", "no" worden false | {{ "true".toBoolean() }} | true |
| .toDateTime() | Converteert string naar Luxon DateTime. Ondersteunt ISO 8601, HTTP, RFC2822, SQL formaten | {{ "2026-03-10".toDateTime() }} | Luxon DateTime object |
| .toSnakeCase() | Converteert naar snake_case | {{ "mijnVeldNaam".toSnakeCase() }} | "mijn_veld_naam" |
| .toTitleCase() | Elk woord begint met hoofdletter | {{ "jan de vries".toTitleCase() }} | "Jan De Vries" |
| .toSentenceCase() | Eerste letter van zin als hoofdletter | {{ "hallo wereld".toSentenceCase() }} | "Hallo wereld" |
| .toJsonString() | Escaped quotes en speciale karakters voor JSON | {{ "tekst met \"quotes\"".toJsonString() }} | Veilige JSON string |
String Functies in de Praktijk
// Voorbeeld 1: Domein extraheren uit e-mail voor lead scoring
{{ $json.email.extractDomain() }}
// "microsoft.com" — enterprise lead!
// Voorbeeld 2: API geeft prijs als string, je hebt een getal nodig
{{ $json.price.toNumber() * 1.21 }}
// "49.99" → 49.99 → 60.49 (incl. BTW)
// Voorbeeld 3: Checkbox-waarde omzetten naar boolean
{{ $json.newsletter_optin.toBoolean() }}
// "yes" → true, "0" → false, "no" → false
// Voorbeeld 4: Datumstring omzetten voor vergelijking
{{ $json.deadline.toDateTime() < $now ? "Verlopen" : "Actief" }}
// Voorbeeld 5: Veldnamen normaliseren van camelCase naar snake_case
{{ $json.fieldName.toSnakeCase() }}
// "fieldName" → "field_name"
JMESPath: Complexe JSON Queries
Als standaard expressions niet genoeg zijn voor complexe geneste data, biedt n8n JMESPath — een querytaal speciaal ontworpen voor het doorzoeken en transformeren van JSON. Je gebruikt het via de $jmespath() functie.
Basissyntax
// Syntax: $jmespath(object, zoekexpressie)
// Stel je hebt deze data:
// {
// "orders": [
// {"id": 1, "status": "paid", "amount": 150},
// {"id": 2, "status": "pending", "amount": 75},
// {"id": 3, "status": "paid", "amount": 200}
// ]
// }
// Filter: alleen betaalde orders
{{ $jmespath($json, "orders[?status=='paid']") }}
// [{id:1, amount:150}, {id:3, amount:200}]
// Projectie: alleen de bedragen
{{ $jmespath($json, "orders[].amount") }}
// [150, 75, 200]
// Filter + projectie: bedragen van betaalde orders
{{ $jmespath($json, "orders[?status=='paid'].amount") }}
// [150, 200]
// Gesorteerd
{{ $jmespath($json, "sort_by(orders, &amount)") }}
// Orders gesorteerd op bedrag
// Maximum waarde
{{ $jmespath($json, "max_by(orders, &amount).id") }}
// 3 — de order met het hoogste bedrag
Geavanceerde JMESPath Voorbeelden
// Multiselect — maak een nieuw object van geselecteerde velden
{{ $jmespath($json, "orders[].{orderId: id, totaal: amount}") }}
// [{orderId: 1, totaal: 150}, {orderId: 2, totaal: 75}, ...]
// Nested data doorzoeken
// Data: {company: {departments: [{name: "IT", employees: 12}, {name: "HR", employees: 5}]}}
{{ $jmespath($json, "company.departments[?employees > `10`].name") }}
// ["IT"]
// Pipe expressies — combineer stappen
{{ $jmespath($json, "orders[?status=='paid'] | [0]") }}
// Eerste betaalde order
// Contains filter
{{ $jmespath($json, "users[?contains(email, '@gmail.com')]") }}
// Alle users met Gmail adres
Let op: parameter volgorde
De JMESPath specificatie gebruikt search(zoekstring, object), maar n8n's implementatie gebruikt $jmespath(object, zoekstring). Als je voorbeelden overneemt uit de JMESPath documentatie, wissel dan de parameters om.
Code Node vs Expressions: Wanneer Gebruik Je Wat?
Dit is een van de meest gestelde vragen. Het korte antwoord: gebruik expressions voor eenvoudige transformaties, de Code node voor complexe logica. Maar laten we specifieker zijn.
Vuistregels
Gebruik Expressions als:
- Je één veld wilt ophalen of transformeren
- De transformatie in één regel past
- Je een ingebouwde functie kunt gebruiken
- Je een simpele if/else nodig hebt (ternary)
- Je met de Edit Fields node werkt
Gebruik de Code Node als:
- Je meerdere items tegelijk wilt verwerken
- Je data wilt groeperen of aggregeren
- Je complexe conditionele logica hebt
- Je error handling nodig hebt (try/catch)
- Je items wilt toevoegen of verwijderen
Lees voor een diepgaande vergelijking de complete Code Node gids.
AI Transform Node: Transformatie in Natuurlijke Taal
Sinds 2025 biedt n8n de AI Transform node — een node die code genereert op basis van een prompt in gewoon Engels (of Nederlands). Je beschrijft wat je wilt, en de AI schrijft de transformatiecode.
Hoe het werkt
- 1. Voeg de AI Transform node toe aan je workflow
- 2. Schrijf een prompt: "Filter alle gebruikers ouder dan 18 en sorteer op achternaam"
- 3. Klik op Generate Code
- 4. De AI genereert JavaScript die past bij je data-structuur
- 5. Test en pas eventueel de prompt aan
Voorbeeld Prompts
// Prompt 1: Eenvoudige filtering
"Remove all items where the email field is empty or null"
// Prompt 2: Data herstructureren
"Combine firstName and lastName into a single fullName field,
calculate the age from birthDate, and add a field isAdult (true if age >= 18)"
// Prompt 3: Aggregatie
"Group all items by the 'category' field and calculate
the total amount and average amount for each group"
// Prompt 4: Format conversie
"Convert each item's date field from DD-MM-YYYY to ISO 8601 format
and change all price fields from cents to euros (divide by 100)"
Kanttekeningen bij de AI Transform node
- Beschikbaarheid: alleen op n8n Cloud plannen, niet op self-hosted
- Leesbaarheid: de gegenereerde code is read-only. Wil je aanpassen? Kopieer naar een Code node
- Complexiteit: werkt minder goed bij grote data-schema's of veel voorafgaande nodes
- Controle: controleer altijd de gegenereerde code voordat je hem in productie zet
10+ Praktische Voorbeelden
1. E-commerce: Order Data Normaliseren
// In de Edit Fields node (JSON mode)
{
"orderId": "{{ $json.id }}",
"klant": "{{ $json.billing.first_name + ' ' + $json.billing.last_name }}",
"email": "{{ $json.billing.email.toLowerCase() }}",
"totaal": "{{ $json.total.toNumber() }}",
"btw": "{{ ($json.total.toNumber() * 0.21).toFixed(2).toNumber() }}",
"producten": "{{ $json.line_items.pluck('name') }}",
"aantalProducten": "{{ $json.line_items.length }}",
"datum": "{{ $json.date_created.toDateTime().toFormat('dd-MM-yyyy') }}"
}
2. CRM: Lead Scoring Berekenen
// Expression in Edit Fields node
"leadScore": "{{
($json.hasField('email') ? 20 : 0) +
($json.hasField('phone') ? 15 : 0) +
($json.email.extractDomain() === 'gmail.com' ? 5 : 15) +
($json.company.isNotEmpty() ? 25 : 0) +
($json.budget.toNumber() > 10000 ? 25 : 10)
}}"
// Score: 0-100 op basis van datakwaliteit
3. API Response: Geneste Data Plat Maken
// JMESPath voor complex geneste API responses
// Data: { results: [{ user: { profile: { name: "Jan" }, orders: [...] } }] }
// Haal alle namen op
{{ $jmespath($json, "results[].user.profile.name") }}
// ["Jan", "Piet", "Klaas"]
// Filter users met meer dan 5 orders
{{ $jmespath($json, "results[?length(user.orders) > `5`].user.profile.name") }}
// ["Jan"] — alleen actieve kopers
4. Data Cleaning: Lege en Ongeldige Waarden Opruimen
// Combinatie van meerdere functies
{
"tags": "{{ $json.tags.compact().unique() }}",
"email": "{{ $json.email ? $json.email.trim().toLowerCase() : '' }}",
"telefoon": "{{ $json.phone ? $json.phone.replaceAll(' ', '').replaceAll('-', '') : '' }}",
"naam": "{{ ($json.name || 'Onbekend').toTitleCase() }}",
"actief": "{{ ($json.status || 'false').toBoolean() }}"
}
5. Batch Verwerking: Items Groeperen met chunk()
// Splits 1000 items in groepen van 50 voor API rate limits
{{ $json.allContacts.chunk(50) }}
// [[contact1..50], [contact51..100], ...]
// Combineer met Loop Over Items node om elke batch te verwerken
// Zie: /blog/n8n-loop-over-items-split-in-batches-complete-gids/
6. Deduplicatie: Unieke Records op Basis van een Veld
// Code Node — Run Once for All Items
const items = $input.all();
const seen = new Set();
const unique = [];
for (const item of items) {
const key = item.json.email.toLowerCase();
if (!seen.has(key)) {
seen.add(key);
unique.push(item);
}
}
return unique;
// Verwijdert dubbele items op basis van e-mailadres
7. Data Mapping: Externe API naar Intern Formaat
// Van Shopify formaat naar je eigen database formaat
{
"product_id": "{{ $json.id }}",
"titel": "{{ $json.title }}",
"prijs_cents": "{{ ($json.variants[0].price.toNumber() * 100).toFixed(0).toNumber() }}",
"voorraad": "{{ $json.variants.pluck('inventory_quantity').sum() }}",
"categorien": "{{ $json.tags ? $json.tags.split(', ').compact() : [] }}",
"gepubliceerd": "{{ $json.status === 'active' }}",
"afbeelding_url": "{{ $json.images.length > 0 ? $json.images[0].src : '' }}",
"sku_lijst": "{{ $json.variants.pluck('sku').compact().unique() }}"
}
8. Conditionele Transformatie: Verschillende Logica per Type
// In combinatie met de IF/Switch node
// Zie: /blog/n8n-if-switch-nodes-conditional-logic-complete-gids/
// Expression die type-specifieke waarden berekent
"label": "{{
$json.type === 'bedrijf'
? $json.bedrijfsnaam
: $json.voornaam + ' ' + $json.achternaam
}}"
"korting_percentage": "{{
$json.klant_type === 'groothandel' ? 25 :
$json.klant_type === 'zakelijk' ? 15 :
$json.klant_type === 'loyal' ? 10 : 0
}}"
9. Datum Transformatie met Luxon
// n8n gebruikt Luxon voor datums (beschikbaar via $now, .toDateTime())
// Huidige datum formatteren
{{ $now.toFormat('dd-MM-yyyy') }} // 10-03-2026
{{ $now.toFormat('cccc d LLLL yyyy') }} // dinsdag 10 maart 2026
// Datum berekeningen
{{ $now.plus({days: 7}).toISO() }} // Over een week
{{ $now.minus({months: 1}).toISO() }} // Een maand geleden
{{ $now.startOf('month').toISO() }} // Eerste dag van de maand
// Verschil berekenen
{{ $now.diff($json.created_at.toDateTime(), 'days').days.toFixed(0) }}
// "45" — aantal dagen sinds aanmaak
// Deadline check
{{ $json.deadline.toDateTime() < $now ? "VERLOPEN" : "OK" }}
10. Data Samenvoegen uit Meerdere Bronnen
// Gebruik de Merge node + Edit Fields om data te combineren
// Zie: /blog/n8n-merge-node-data-combineren-complete-gids/
// Na een Merge node kun je velden samenvoegen:
{
"klant_id": "{{ $json.customer_id }}",
"naam": "{{ $json.name }}",
"laatste_order_datum": "{{ $json.last_order_date }}",
"totaal_besteed": "{{ $json.orders.pluck('amount').sum() }}",
"gemiddeld_per_order": "{{ $json.orders.pluck('amount').average().toFixed(2).toNumber() }}",
"duurste_order": "{{ $json.orders.pluck('amount').max() }}",
"segment": "{{
$json.orders.pluck('amount').sum() > 10000 ? 'VIP' :
$json.orders.pluck('amount').sum() > 1000 ? 'Regulier' : 'Starter'
}}"
}
11. Webhook Data Valideren en Transformeren
// Code Node voor complete validatie + transformatie
const item = $json;
const errors = [];
// Validatie
if (!item.email || !item.email.includes('@')) {
errors.push('Ongeldig e-mailadres');
}
if (!item.name || item.name.trim().length < 2) {
errors.push('Naam is verplicht (min. 2 karakters)');
}
if (item.amount && isNaN(Number(item.amount))) {
errors.push('Bedrag moet een getal zijn');
}
if (errors.length > 0) {
return {
json: { valid: false, errors, originalData: item }
};
}
// Transformatie (alleen als validatie slaagt)
return {
json: {
valid: true,
email: item.email.trim().toLowerCase(),
name: item.name.trim(),
amount: Number(item.amount),
domain: item.email.split('@')[1],
received_at: new Date().toISOString()
}
};
Veelgemaakte Fouten bij Data Transformatie
Na honderden workflows gebouwd te hebben, zijn dit de fouten die steeds terugkomen. Herken ze voordat ze je workflows breken.
Fout 1: Geen null-checks bij optionele velden
// FOUT: crasht als address niet bestaat
{{ $json.address.city }}
// GOED: optional chaining
{{ $json.address?.city || 'Onbekend' }}
// GOED: hasField check
{{ $json.hasField('address') ? $json.address.city : 'Onbekend' }}
Fout 2: String en Number door elkaar gebruiken
// FOUT: "10" + "20" = "1020" (string concatenatie)
{{ $json.price + $json.tax }}
// GOED: expliciet converteren
{{ $json.price.toNumber() + $json.tax.toNumber() }}
Fout 3: Array methode op een niet-array
// FOUT: crasht als tags een string is i.p.v. array
{{ $json.tags.unique() }}
// GOED: controleer eerst het type
{{ Array.isArray($json.tags) ? $json.tags.unique() : [$json.tags] }}
Fout 4: Multi-line code in expressions
// FOUT: expressions kunnen geen multi-line code bevatten
{{
const x = $json.price;
return x * 1.21;
}}
// GOED: gebruik een ternary of verplaats naar Code node
{{ $json.price * 1.21 }}
Fout 5: JMESPath parameter volgorde verkeerd
// FOUT: JMESPath spec volgorde (werkt niet in n8n)
{{ $jmespath("users[].name", $json) }}
// GOED: n8n volgorde — object eerst, query tweede
{{ $jmespath($json, "users[].name") }}
Fout 6: Code node return formaat vergeten
// FOUT: return geen array van items
return { name: "Jan" };
// GOED: wrap in array met json key
return [{ json: { name: "Jan" } }];
// OOK GOED (n8n voegt json wrapper automatisch toe sinds v0.166.0):
return [{ name: "Jan" }];
Cheat Sheet: Snelle Referentie
n8n Data Transformatie Cheat Sheet
--- VARIABELEN ---
$json.veld huidige item data
$input.all() alle input items
$input.first() eerste input item
$input.last() laatste input item
$node["Name"].json data van specifieke node
$now huidig tijdstip (Luxon)
$today vandaag 00:00 (Luxon)
$env.KEY environment variabele
$workflow.id workflow ID
$execution.id executie ID
$itemIndex huidige item index
--- STRINGS ---
.extractDomain() domein uit email/URL
.toNumber() string naar getal
.toBoolean() string naar boolean
.toDateTime() string naar Luxon datum
.toSnakeCase() camelCase naar snake_case
.toTitleCase() elk woord hoofdletter
.toSentenceCase() eerste letter hoofdletter
--- ARRAYS ---
.pluck('key') haal veld uit objecten
.unique() verwijder duplicaten
.compact() verwijder null/lege waarden
.chunk(n) splits in groepen van n
.renameKeys(a, b) hernoem keys in objecten
.sum() / .average() som / gemiddelde
.min() / .max() kleinste / grootste
.union(arr) combineer + dedup
.difference(arr) verschil tussen arrays
.intersection(arr) overlap tussen arrays
.randomItem() willekeurig element
.append(item) voeg element toe
.smartJoin() array objecten samenvoegen
--- OBJECTEN ---
.hasField('key') bestaat het veld?
.isEmpty() is het object leeg?
.isNotEmpty() heeft het velden?
.keepFieldsContaining(val)
filter op waarde
Object.keys(obj) alle keys als array
Object.values(obj) alle waarden als array
--- JMESPATH ---
$jmespath($json, "users[].name") projectie
$jmespath($json, "items[?price > `100`]") filteren
$jmespath($json, "sort_by(items, &name)") sorteren
$jmespath($json, "max_by(items, &price).name") max waarde
Samenvatting: Je Data Transformatie Toolbox
Data transformatie in n8n is een gelaagd systeem. Kies de juiste tool voor de juiste klus:
Laag 1: Edit Fields Node
Visuele drag-and-drop mapping. Geen code nodig. Gebruik voor standaard veld-mapping en hernoemen.
Laag 2: Expressions
Inline transformaties met {{ }}. Array, object en string functies. Voor de meeste dagelijkse transformaties.
Laag 3: JMESPath
Query-taal voor complex geneste JSON. Filteren, sorteren en projecteren in één expression.
Laag 4: Code Node
Volledige JavaScript of Python. Voor complexe logica, loops, aggregatie en error handling.
Laag 5: AI Transform
Beschrijf je transformatie in natuurlijke taal. De AI genereert de code. Alleen op n8n Cloud.
Begin altijd bij de eenvoudigste laag die je probleem oplost. Open geen Code node als een expression volstaat. Gebruik geen JMESPath als .pluck() het werk doet. En test je transformaties altijd eerst met een klein aantal items voordat je ze loslaat op je volledige dataset.
Volgende Stappen
- Experimenteer met de array functies in je eigen workflows
- Probeer JMESPath uit op een complex API response
- Bouw een data cleaning workflow met Edit Fields + expressions
- Print dit cheat sheet uit en hang het naast je scherm