Power Plus - JSONata: Data Transformation Reference
Reference for JSONata, the expression language used throughout Power Plus for querying, transforming, and templating JSON data. Covers basic navigation, filters, predicates, common built-in functions ($map, $filter, $formatNumber, $fromMillis, $millis, etc.), and the [[ ... ]] template syntax used in renderer fields.
JSONata is the expression language used throughout the Power Plus framework for data transformation, field mapping, and templating. It lets you extract, transform, and format data from your datasources without writing code.
JSONata is used in two places:
-
Datasource queries — Transform raw API responses into a clean array of items.
-
Renderer field expressions — Map data fields to display content using the
[[ ... ]]template syntax.
The [[
... ]] Template Syntax
In renderer fields (Content, Value, Hover Content, Link URL, etc.), you embed JSONata expressions inside double brackets:
[[object.values.name]]
The object variable refers to the current data item being rendered.
Text Content Examples
Simple field access:
[[object.name]]
Formatted number:
[[ $formatNumber(object.hs_price_eur, "#,##0.00") ]]€
Date formatting:
[[ $fromMillis(object.millis, "[D01]/[M01]/[Y0001]") ]]
Conditional content:
[[if object.discount]]<span class="badge">SALE</span>[[endif]]
Loop through arrays:
[[ for item in object.values.tags ]]
<span class="tag">[[item.name]]</span>
[[ endfor ]]
Nested property access:
[[object.values.image.url]]
Image Value Examples
[[ object.values.image.url ]]
[[ object.hs_images ? object.hs_images.$split(',')[0] : '' ]]
Link URL Examples
[[object.values.link]]
[[if object.hs_sku]]product/[[object.hs_sku]][[endif]]
[[object.absolute_url]]
Datasource Query Examples
In the JSON Datasource’s JSON Query field, you write pure JSONata (no [[ ]] brackets needed).
Extract Items from an API Response
results
Extracts the results array from {
"total": 42, "results": [...] }.
Navigate Nested Structures
data.items.records
Filter Items
items[status = 'active']
Only returns items where status is “active”.
Sort Items
items^(name)
Sorts by name ascending. Use ^(>name) for descending.
Transform with $map()
Convert an array of objects into a different shape:
$map(jobs, function($v) {
$merge([$v, {
'department': $v.metadata[name.$contains('Department')].value,
'employment_type': $v.metadata[name.$contains('Employment')].value
}])
})
This takes each job object, finds metadata entries by name, and merges them as flat properties.
Reshape Parallel Arrays
Convert parallel arrays (common in weather/time-series APIs) into an array of objects:
$map($.hourly.time, function($v, $i) {
{
"id": $i,
"time": $v,
"temp": $.hourly.temperature_2m[$i],
"wind": $.hourly.windspeed_10m[$i],
"millis": $toMillis($v & ":00")
}
})
Common JSONata Functions
|
Function |
Description |
Example |
|---|---|---|
|
|
Convert to string |
|
|
|
Convert to number |
|
|
|
Array/string length |
|
|
|
Join array into string |
|
|
|
Split string into array |
|
|
|
Check substring |
|
|
|
Replace text |
|
|
|
Trim whitespace |
|
|
|
Uppercase |
|
|
|
Lowercase |
|
|
|
Current ISO timestamp |
|
|
|
Current time in ms |
|
|
|
Parse ISO to ms |
|
|
|
Format ms to date string |
|
|
|
Format number |
|
|
|
Sum numbers |
|
|
|
Average |
|
|
|
Minimum |
|
|
|
Maximum |
|
|
|
Count items |
|
|
|
Sort with comparator |
|
|
|
Filter array |
|
|
|
Transform each item |
|
|
|
Reduce to single value |
|
|
|
Merge objects |
|
|
|
Get object keys |
|
|
|
Get value by key |
|
|
|
Get type |
|
Date Format Patterns
The $fromMillis() function uses XPath-style date format patterns:
|
Pattern |
Description |
Example |
|---|---|---|
|
|
Four-digit year |
|
|
|
Two-digit month |
|
|
|
Two-digit day |
|
|
|
Two-digit hour (24h) |
|
|
|
Two-digit minute |
|
|
|
Two-digit second |
|
|
|
Month name |
|
|
|
Day of week name |
|
Example: $fromMillis(object.date,
"[D01]/[M01]/[Y0001] [H01]:[m01]") → 15/03/2024
14:30
Number Format Patterns
The $formatNumber() function uses these patterns:
|
Pattern |
Description |
Example |
|---|---|---|
|
|
Optional digit |
|
|
|
Required digit (zero-padded) |
|
|
|
Decimal point |
|
|
|
Thousands separator |
|
Template Control Flow
Conditional (if/endif)
[[if object.discount]]
<span class="discount">-[[object.discount]]%</span>
[[endif]]
Loop (for/endfor)
[[ for tag in object.values.tags ]]
<span class="tag">[[tag.name]]</span>
[[ endfor ]]
Ternary (inline conditional)
[[ object.active ? "Active" : "Inactive" ]]
Filter Expressions
In filter value fields, you can use JSONata for dynamic values:
[[$millis()]] → current time in milliseconds
[[$now()]] → current ISO timestamp
$cartProductIds() → custom extension: array of product IDs in the cart
Data-Schema Queries
For data-schema filters, JSONata navigates the auto-generated schema:
schema.properties[name='values'].properties[name='category'].properties[name='name'].values^(value)
This finds all unique values of values.category.name in the dataset schema, sorted alphabetically.
Learn More
-
JSONata Exerciser (try expressions online): https://try.jsonata.org/
-
Full JSONata Documentation: https://docs.jsonata.org/
-
JSONata GitHub: https://github.com/jsonata-js/jsonata