Working with JSON in JS, the easy way! JSONata
Eduardo Marques
Posted on February 10, 2021
Data structures are one of the most important elements in any programming language. It allows us to structure the data in a consistent way and to perform operations that require some patterns. Without a pattern it is hard for any developer to figure out an efficient way to extract or manipulate the data.
As an example, JSON
is a very well known format that most of us uses every day.
When working with it, there are operations we do regularly, such as querying, filtering, sorting, grouping and others.
Recently, while working on a project, I needed two things, proper functions for all of these operations, and some sort of expressions for external users. I quickly realised that this wasn’t a small task.
We, as Software Developers, always get excited with these tasks, we can get creative and explore a lot, but we should not try to reinvent the wheel. I recently read a great book called Getting real, it really helped me focus on my goals and, in this particular case, quickly realise that before trying to implement this I should look for existent solutions.
And that’s when I came across JSONata, a really powerful library that did everything what I was looking for and more!
In this article I would like to give you a quick introduction to JSONata and show how easy it is to work with JSON.
Usage
const jsonata = require('jsonata');
const data = [
{
field: 'some-field',
createdAt: '2021-01-03T21:58:31.000Z'
}
];
const expression = jsonata('$[createdAt="2021-01-03T21:58:31.000Z"]');
const result = expression.evaluate(data);
Expressions for your day to day needs
JSONata helps us solve the most common cases when it comes to extracting data from JSON. In this article I cover some basic expressions that will help you get started with the library.
We will use the following JSON to test our expressions.
[
{
"uniqueId": "9157c740159e4ff18b4a42d4a0c39622",
"data": {
"name": "Eduardo",
"phone": 999888727,
"age": 30
},
"createdAt": "2021-02-03T21:54:37.000Z",
"updatedAt": "2021-02-03T21:54:37.000Z"
},
{
"uniqueId": "66a1212c55ce47f9bc055e6c331b7af3",
"data": {
"name": "Miguel",
"age": 17,
"phone": 999888777
},
"createdAt": "2021-02-03T21:56:54.000Z",
"updatedAt": "2021-02-03T21:56:54.000Z"
},
{
"uniqueId": "86011b52ebc640aeba53a6e09a9d9773",
"data": {
"name": "Marco",
"age": 18
},
"createdAt": "2021-02-04T21:57:59.000Z",
"updatedAt": "2021-02-04T21:57:59.000Z"
},
{
"uniqueId": "0f6586aa7ccf4901a3f066eeeea69116",
"data": {
"name": "Sergio",
"age": 28,
"jobDetails": {
"company": "SpaceY"
}
},
"createdAt": "2021-02-07T22:02:50.000Z",
"updatedAt": "2021-02-07T22:02:50.000Z"
}
]
You can try out these expressions at https://try.jsonata.org.
Simple queries
data.name
Gets an array of names.
Result
[
"Eduardo",
"Miguel",
"Marco",
"Sergio"
]
$[1]
Gets the second element.
Result
{
"uniqueId": "66a1212c55ce47f9bc055e6c331b7af3",
"data": {
"name": "Miguel",
"age": 17,
"phone": 999888777
},
"createdAt": "2021-02-03T21:56:54.000Z",
"updatedAt": "2021-02-03T21:56:54.000Z"
}
$[0]data.name
Gets the name of the first element.
Result
"Eduardo"
Filtering
$[data.name="Eduardo"]
Filters records in the array containing the path data.name and matching Eduardo.
Result
{
"uniqueId": "9157c740159e4ff18b4a42d4a0c39622",
"data": {
"name": "Eduardo",
"phone": 999888727,
"age": 30
},
"createdAt": "2021-02-03T21:54:37.000Z",
"updatedAt": "2021-02-03T21:54:37.000Z"
}
$[data.jobDetails]
Filters records in the array containing the path data.jobDetails.
Result
{
"uniqueId": "0f6586aa7ccf4901a3f066eeeea69116",
"data": {
"name": "Sergio",
"age": 28,
"jobDetails": {
"company": "SpaceY"
}
},
"createdAt": "2021-02-07T22:02:50.000Z",
"updatedAt": "2021-02-07T22:02:50.000Z"
}
$[data.age > 16 and data.age < 20]
Filters records in the array with data.age between 16 and 20.
Result
[
{
"uniqueId": "66a1212c55ce47f9bc055e6c331b7af3",
"data": {
"name": "Miguel",
"age": 17,
"phone": 999888777
},
"createdAt": "2021-02-03T21:56:54.000Z",
"updatedAt": "2021-02-03T21:56:54.000Z"
},
{
"uniqueId": "86011b52ebc640aeba53a6e09a9d9773",
"data": {
"name": "Marco",
"age": 18
},
"createdAt": "2021-02-04T21:57:59.000Z",
"updatedAt": "2021-02-04T21:57:59.000Z"
}
]
Pagination
$[[0..1]]
Gets the first 2 elements.
Result
[
{
"uniqueId": "9157c740159e4ff18b4a42d4a0c39622",
"data": {
"name": "Eduardo",
"phone": 999888727,
"age": 30
},
"createdAt": "2021-02-03T21:54:37.000Z",
"updatedAt": "2021-02-03T21:54:37.000Z"
},
{
"uniqueId": "66a1212c55ce47f9bc055e6c331b7af3",
"data": {
"name": "Miguel",
"age": 17,
"phone": 999888777
},
"createdAt": "2021-02-03T21:56:54.000Z",
"updatedAt": "2021-02-03T21:56:54.000Z"
}
]
$[[2..4]]
Gets the second 2 elements.
Result
[
{
"uniqueId": "86011b52ebc640aeba53a6e09a9d9773",
"data": {
"name": "Marco",
"age": 18
},
"createdAt": "2021-02-04T21:57:59.000Z",
"updatedAt": "2021-02-04T21:57:59.000Z"
},
{
"uniqueId": "0f6586aa7ccf4901a3f066eeeea69116",
"data": {
"name": "Sergio",
"age": 28,
"jobDetails": {
"company": "SpaceY"
}
},
"createdAt": "2021-02-07T22:02:50.000Z",
"updatedAt": "2021-02-07T22:02:50.000Z"
}
]
Sorting
$[] ~> $sort(function($a,$b){ $a.data.age > $b.data.age })
Sorts the results by ascending age. In this expression we use the $sort function to sort the results.
Result
[
{
"uniqueId": "66a1212c55ce47f9bc055e6c331b7af3",
"data": {
"name": "Miguel",
"age": 17,
"phone": 999888777
},
"createdAt": "2021-02-03T21:56:54.000Z",
"updatedAt": "2021-02-03T21:56:54.000Z"
},
{
"uniqueId": "86011b52ebc640aeba53a6e09a9d9773",
"data": {
"name": "Marco",
"age": 18
},
"createdAt": "2021-02-04T21:57:59.000Z",
"updatedAt": "2021-02-04T21:57:59.000Z"
},
{
"uniqueId": "0f6586aa7ccf4901a3f066eeeea69116",
"data": {
"name": "Sergio",
"age": 28,
"jobDetails": {
"company": "SpaceY"
}
},
"createdAt": "2021-02-07T22:02:50.000Z",
"updatedAt": "2021-02-07T22:02:50.000Z"
},
{
"uniqueId": "9157c740159e4ff18b4a42d4a0c39622",
"data": {
"name": "Eduardo",
"phone": 999888727,
"age": 30
},
"createdAt": "2021-02-03T21:54:37.000Z",
"updatedAt": "2021-02-03T21:54:37.000Z"
}
]
Working with dates
Combining $filter and $toMillis
$[] ~> $filter(function($value){
$toMillis($value.createdAt)>$toMillis("2021-02-07T22:00:00.000Z")
})
$toMillis converts a ISO 8601 date to milliseconds. In this example we filter all the elements created after 2021-02-07 22:00:00.
Result
{
"uniqueId": "0f6586aa7ccf4901a3f066eeeea69116",
"data": {
"name": "Sergio",
"age": 28,
"jobDetails": {
"company": "SpaceY"
}
},
"createdAt": "2021-02-07T22:02:50.000Z",
"updatedAt": "2021-02-07T22:02:50.000Z"
}
And this is all for now. I hope you find this article useful, and don't forget to give JSONata a go!
PS: In case you are wondering, I’m not the author and I'm not part of the team, I just liked it so much that I thought it would be worth sharing with others! All the Kudos goes to the JSONata team!
Posted on February 10, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.