DEV Community

loading...

Working with JSON in JS, the easy way! JSONata

edumqs profile image Eduardo Marques ・4 min read

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);
Enter fullscreen mode Exit fullscreen mode

 

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"
  }
]
Enter fullscreen mode Exit fullscreen mode

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"
]
Enter fullscreen mode Exit fullscreen mode

$[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"
}
Enter fullscreen mode Exit fullscreen mode

$[0]data.name

Gets the name of the first element.

Result

"Eduardo"
Enter fullscreen mode Exit fullscreen mode

 

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"
}
Enter fullscreen mode Exit fullscreen mode

$[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"
}
Enter fullscreen mode Exit fullscreen mode

$[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"
  }
]
Enter fullscreen mode Exit fullscreen mode

 

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"
  }
]
Enter fullscreen mode Exit fullscreen mode

$[[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"
  }
]
Enter fullscreen mode Exit fullscreen mode

 

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"
  }
]
Enter fullscreen mode Exit fullscreen mode

 

Working with dates

 

Combining $filter and $toMillis

$[] ~> $filter(function($value){
    $toMillis($value.createdAt)>$toMillis("2021-02-07T22:00:00.000Z")
})
Enter fullscreen mode Exit fullscreen mode

$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"
}
Enter fullscreen mode Exit fullscreen mode

 
 
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!

Discussion (0)

pic
Editor guide