In most cases, you only need two methods to modify JSON objects with JSONata. If you are dealing with a simple object whose structure isn't likely to change, you can easily combine an array of objects with JSONata's object function $merge()
. If you are trying to modify or delete key-value pairs in a complex object with dynamic keys multiple levels deep, it's best to use the object transform operator ... ~> | ... | ... |
.
Unless otherwise stated, the following examples assume the JSON input object ($
) is
{
"user": {
"firstName": "Alex",
"surname": "Watson",
"age": 22,
"contactDetails": {
"address": {
"street": "Burley Park",
"city": "Leeds",
"postcode": "AO19 2HN"
},
"company": {
"name": "Smart Contractors",
"address": {
"street": "Main St",
"city": "London",
"postcode": "LN19 2FT"
}
}
}
}
}
Add a new key-value pair
There are two ways to add a new key-value pair, such as { "userCount": 1 }
, to the JSON input so it becomes
{
"user": {
"firstName": "Alex",
"surname": "Watson",
"age": 22,
"contactDetails": "..."
},
"userCount": 1
}
1. Using $merge()
Calling this JSONata expression will append the new key-value pair to the JSON input. The function is a good choice when dealing with simple objects.
$merge([$, { "userCount": 1 }])
2. Using the object transform operator
Using the transform operator will also append the new key-value pair to the JSON input.
$ ~> |$|{ "userCount": 1 }|
However, the operator is more convenient when adding a new key-value pair to an object with dynamic keys, especially a nested key-value pair.
For example, to add { "email": [email protected] }
to $.user.contactDetails
, pass the JSON input object to the transform operator ($ ~>
), then navigate to the target key-value pair (|user.contactDetails|
), and provide the new value (|{ "email": "[email protected]" }|
) like in this expression
$ ~> |user.contactDetails|{ "email": "[email protected]" }|
which will return
{
"user": {
"firstName": "Alex",
"surname": "Watson",
"age": 22,
"contactDetails": {
"address": {
"street": "Burley Park",
"city": "Leeds",
"postcode": "AO19 2HN"
},
"email": "[email protected]",
"company": "..."
}
}
}
Modify an existing key-value pair
1. Using $merge()
If you are dealing with a simple object whose structure isn't likely to change, such as
{
"a": 1,
"b": 2
}
you can overwrite the target key-value pair with the expression
$merge([$, { "a": 10 }])
which will modify the value of the key a
from 1
to 10
. If you have an object like the JSON input declared at the beginning of this post, it is safer and easier to make modifications with the transform operator.
2. Using the object transform operator
For example, to change the postcode in $.user.contactDetails.address
in the original JSON input
{
"user": {
"firstName": "Alex",
"surname": "Watson",
"age": 22,
"contactDetails": {
"address": {
"street": "Burley Park",
"city": "Leeds",
"postcode": "AO19 2HN"
},
"company": "..."
}
}
}
pass the input object to the transform operator ($ ~>
), then navigate to the target key-value pair (|user.contactDetails.address|
), and provide the new value (|{ "postcode": "AO07 1BG" }|
) like in this expression
$ ~> |user.contactDetails.address|{ "postcode": "AO07 1BG" }|
Remove an existing key-value pair
The syntax for the object transform operator is $ ~> | location | update [, delete] |
. To remove an object key or an entire nested object, pass an empty object in the update
clause and the name of the key as a string in the optional delete
clause.
To remove all company details from the JSON input, for example, use the expression
$ ~> |user.contactDetails|{}, "company"|
which will return
{
"user": {
"firstName": "Alex",
"surname": "Watson",
"age": 22,
"contactDetails": {
"address": {
"street": "Burley Park",
"city": "Leeds",
"postcode": "AO19 2HN"
}
}
}
}
Useful resources
To learn more about the two methods, visit the official JSONata documentation for the $merge()
function and the object transform operator.