A TypeScript/JavaScript library that provides a simple way of accessing objects inside JSON using paths
npm install @jsonhero/path
You can require
const { JSONHeroPath } = require('@jsonhero/path');
Or if you're using TypeScript:
import { JSONHeroPath } from '@jsonhero/path';
Given the following JSON variable called employees
let employees = {
people: [
{
name: 'Matt',
age: 36,
favouriteThings: ['Monzo', 'The Wirecutter', 'Jurassic Park'],
},
{
name: 'James',
age: 39,
favouriteThings: ['Far Cry 1', 'Far Cry 2', 'Far Cry 3'],
},
{
name: 'Eric',
age: 38,
favouriteThings: ['Bitcoin'],
},
{
name: 'Dan',
age: 34,
favouriteThings: ['Frasier'],
},
],
count: 4,
};
A simple query to get the 2nd person's name. Note that you can just include index numbers to access array items (0 = first item)
let path = new JSONHeroPath('$.people.1.name');
let name = path.first(employees);
//name = 'James'
let names = path.all(employees);
//names = ['James']
Let's get all the people
let path = new JSONHeroPath('$.people');
let allPeople = path.all(employees);
//allPeople is set to the array of people
There are only two methods you can perform with a path:
first()
returns the first matching resultall()
returns all the matching results in an array
A $
is placed at the start of a path. If you don't add this, it will just do it automatically for you.
Let's get all the names
let path = new JSONHeroPath('$.people.*.name');
let allNames = path.all(employees);
//allNames = ['Matt', 'James', 'Eric', 'Dan']
Now everyone's favourite things
let path = new JSONHeroPath('$.people.*.favouriteThings.*');
let allFavouriteThings = path.all(employees);
//allFavouriteThings = ['Monzo', 'The Wirecutter', 'Jurassic Park', 'Far Cry 1', 'Far Cry 2', 'Far Cry 3', 'Bitcoin', 'Frasier']
We can slice arrays (in the exact same way as the JavaScript .slice() function).
Offset the start index
let path = new JSONHeroPath('$.people.[1:]');
let skipFirstPerson = path.all(employees);
// skipFirstPerson will have everyone but the first person in
Restrict the end index
let path = new JSONHeroPath('$.people.[1:2]');
let justTheSecondPerson = path.all(employees);
// justTheSecondPerson will have only the second person in (start index is 1 and the end won't include index 2)
Negative end indexes remove items from the end of an array
let path = new JSONHeroPath('$.people.[:-1]');
let excludeLastPerson = path.all(employees);
// excludeLastPerson will have everyone except the last person
let path = new JSONHeroPath('$.people.*.favouriteThings.*');
// pass this optional object with `includePath` set to true
let results = path.all(testObject1, { includePath: true });
let firstResult = results[0];
//this variable will be an object like this
//{
// value: 'Monzo',
// path: a JSONHeroPath for this element
//}
let path = new JSONHeroPath('$.people.*.favouriteThings');
let parent = path.parent;
// will be a new path: '$.people.*'
let root = path.root;
// will be a new path: '$'
let child = path.child('2');
//will be a new path: '$.people.*.favouriteThings.2'
A path is an array of path components. You can access them directly if you'd like.
You can check if a component is an array type, which is true for wildcards and indexes (e.g. 0)
let path = new JSONHeroPath('$.people.2.favouriteThings.*');
let rootComponent = path.components[0];
let rootComponentIsArray = rootComponent.isArray;
//is false
let personIndexComponent = path.components[2];
let personIndexComponentIsArray = personIndexComponent.isArray;
//is true
let wildcardComponent = path.components[4];
let wildcardComponentIsArray = wildcardComponent.isArray;
//is true
You can update values in an object at the specified path.
Overwriting a single object at a path:
let path = new JSONHeroPath('$.people.1');
//this will overwrite the entire object at that path
path.set(employees, {
name: 'James',
age: 100,
favouriteThings: ['Far Cry 1', 'Far Cry 2', 'Far Cry 3', 'Far Cry 4', 'Far Cry 5', 'Far Cry 6'],
});
This will overwrite all the objects at the path:
let path = new JSONHeroPath('$.people.*.favouriteThings');
//this will set everyone's favourite things to be an array with just Jurassic Park in it
path.set(employees, ['Jurassic Park']);
You can merge values into arrays and objects.
For an array this will append the passed in values to the end of the array
let path = new JSONHeroPath('$.people.*.favouriteThings');
//this will add Groundhog Day and Milkshakes to everyone's favourite things
path.merge(employees, ['Groundhog Day', 'Milkshakes']);
For an object, this will overwrite properties that already exist and add any that don't
let path = new JSONHeroPath('$.people.*');
//this will update everyone's age to be 21 and add a new hairColour property with a value of Brown
path.merge(employees, {
age: 21,
hairColour: 'Brown',
});