json pointer - failsafe data retrieval from js and json objects
npm install @sagold/json-pointer  !Types

json-pointer implementation following RFC 6901 to work with serializable paths into javascript data structures.
api | usage examples | fragment identifier | breaking changes
install
yarn add @sagold/json-pointer
usage
``js
import { get, set, remove } from '@sagold/json-pointer';
const data = {};
get(data, '/path/to/nested/item'); // undefined
set(data, '/path/to/nested/item', 123); // { path: { to: { nested: { item: 123 }}}
remove(data, '/path/to/nested/item'); // { path: { to: { nested: { }}}
`
As the _error handling_ is not further specified, this implementation will return undefined for any invalid
pointer/missing data, making it very convenient to work with uncertain data.
| method | description
| ----------------------------------------- | -------------------------------------------------------------
| get(data, pointer) -> value | returns the value at given pointer
| set(data, pointer, value) -> data | sets the value at the given path
| remove(data, pointer) -> data | removes a property from data
| join(...pointers) -> pointer | joins multiple pointers to a single one
| split(pointer) -> [array] | returns a json-pointer as an array
| splitLast(pointer) -> [pointer, property] | returns parent-pointer and last property
> The methods get, set, remove and join also accept a list of properties as pointer. Using join with a listjoin(properties:string[], isURI=false) -> string
> of properties, its signature changes to
> get(data:object|array, pointer:string|array, defaultValue:any) -> value:any
returns nested values
`js
import pointer from '@sagold/json-pointer';
const data = {
parent: {
child: {
title: 'title of child'
}
}
}
const titleOfChild = pointer.get(data, '/parent/child/title'); // output: 'title of child'
console.log(pointer.get(data, '/parent/missing/path')); // output: undefined
`
and may optionally return a default value with
`js`
import pointer from '@sagold/json-pointer';
const value = pointer.get({}, "/invalid/value", 42);
console.log(value); // output: 42
get also accepts a list of properties as pointer (e.g. split-result)
`js`
const titleOfChild = pointer.get(data, ['parent', 'child', 'title']); // output: 'title of child'
console.log(pointer.get(data, ['parent', 'missing', 'path'])); // output: undefined
> set(data:object|array, pointer:string|array, value:any) -> data:object|array
changes a nested value
`js
import pointer from '@sagold/json-pointer';
var data = {
parent: {
children: [
{
title: 'title of child'
}
]
}
};
pointer.set(data, '/parent/children/1', { title: 'second child' });
console.log(data.parent.children.length); // output: 2
`
and may be used to build data
`js`
import pointer from '@sagold/json-pointer';
const data = pointer.set({}, '/list/[]/value', 42);
console.log(data); // output: { list: [ { value: 42 } ] }
set also accepts a list of properties as pointer (e.g. split-result)
`js`
import pointer from '@sagold/json-pointer';
const data = pointer.set({}, ['list', '[]', 'value'], 42);
console.log(data); // output: { list: [ { value: 42 } ] }
#### behaviour using set
set will create arrays when encountering a number
`js`
pointer.set({}, ['list', '1', 'value'], 42);
// { list: [undefined, { value: 42 }] }
alternatively you may use array-syntax [index]
`js`
pointer.set({}, ['list', '[1]', 'value'], 42);
// { list: [undefined, { value: 42 }] }
append items using empty array syntax []
`js`
pointer.set({ list: [1, 2] }, ['list', '[]', 'value'], 42);
// { list: [1, 2, { value: 42 }] }
create object using object syntax {index}
`js`
pointer.set({}, ['list', '{1}', 'value'], 42);
// { list: { 1: { value: 42 } }
> ⚠️ set prefers existing data-type over specified data-types. For example: Setting an object for an existing array, will keep the object intact:`
>
> js`
> pointer.set({ list: []}, ['list', '{0}', 'value'], 42);
> // { list: [{ value: 42 }] }
>
> remove(data:object|array, pointer:string|array) -> data:object|array
deletes a nested property or item
`js`
import pointer from '@sagold/json-pointer';
const data = pointer.remove({ parent: { arrayOrObject: [ 0, 1 ] }}, '/parent/arrayOrObject/1');
console.log(data.parent.arrayOrObject); // output: [0]
remove also accepts a list of properties as pointer (e.g. split-result)
`js`
import pointer from '@sagold/json-pointer';
const data = pointer.remove({ parent: { arrayOrObject: [ 0, 1 ] }}, ['parent', 'arrayOrObject', '1']);
console.log(data.parent.arrayOrObject); // output: [0]
> split(pointer:string) -> properties:array
returns a json-pointer as a list of (escaped) properties
`js`
import pointer from '@sagold/json-pointer';
const list = pointer.split('/parent/arrayOrObject/1');
console.log(list); // output: ['parent', 'arrayOrObject', '1']
In order to resolve a list of properties, you can directly pass the list to get, set or remove
`js`
import pointer from '@sagold/json-pointer';
const data = { a: { b: true } };
const list = pointer.split('/a/b');
console.log(pointer.get(data, list)); // output: true
> splitLast(pointer:string) -> [pointer, property]
separates json-pointers last property and returns both values as [parent-pointer, property]
`js`
import pointer from '@sagold/json-pointer';
const [parent, property] = pointer.splitLast('/parent/arrayOrObject/1');
console.log(parent); // output: '/parent/arrayOrObject'
console.log(property); // output: '1'
> join(...pointers:string[]) -> pointer:string
joins all arguments to a valid json pointer
`js`
import pointer from '@sagold/json-pointer';
const key = 'my key';
console.log(pointer.join('root', key, '/to/target')); // output: '/root/my key/to/target'
and joins relative pointers as expected
`js`
import pointer from '@sagold/json-pointer';
console.log(pointer.join('/path/to/value', '../object')); // output: '/path/to/object'
in order to join an array received from split, you can use join(properties:string[], isURI=false) -> string to
retrieve a valid pointer
`js`
import pointer from '@sagold/json-pointer';
const list = pointer.split('/my/path/to/child');
list.pop();
console.log(pointer.join(list)); // output: '/my/path/to'
To join an array of pointers, you must use it with join(...pointers) or all pointers will be treated as properties:
`js
import pointer from '@sagold/json-pointer';
const path = pointer.join(...['/path/to/value', '../object']);
console.log(path); // output: '/path/to/object'
// passing the array directly, will treat each entry as a property, which will be escaped and resolves to:
pointer.join(['/path/to/value', '../object']); // output: '/~1path~1to~1value/..~1object'
`
All methods support a leading uri fragment identifier (#), which will ensure that property-values are uri decoded
when resolving the path within data. This also ensures that any pointer is returned uri encoded with a leading #. e.g.
`js
import pointer from '@sagold/json-pointer';
// get
const value = pointer.get({ 'my value': true }, '#/my%20value');
console.log(value); // output: true
// join
const pointer = pointer.join('#/my value/to%20parent', '../to~1child');
console.log(pointer); // output: '#/my%20value/to~1child'
// join an array of properties
const uriPointer = pointer.join(['my value', 'to~1child'], isURI = true);
console.log(uriPointer); // output: '#/my%20value/to~1child'
`
Additionally join(...pointers, isURI) may be used to enforce the pointer type, which is helpful in sanitizing inputs
`js
const uriPointer = pointer.join('my pointer', 'to', 'property', isURI = true);
console.log(uriPointer); // output: '#/my%20pointer/to/property'
const uriSimple = pointer.join('/my pointer/to/property', isURI = true);
console.log(uriSimple); // output: '#/my%20pointer/to/property'
const pointer = pointer.join('#/my pointer', 'to', 'property', isURI = false);
console.log(pointer); // output: '/my pointer/to/property'
`
- 2025/10/27 v7.2.0v7
- changed exports to support esm
- 2025/01/14 with pointer.set
- creates arrays using numbers as properties /1 when the data is null or an array (previously created objects)pointer.set
- creates objects for numbers when using object-syntax /{1} (previously unsupported)v6
- 2024/04/06 with , selection of empty properties is supported:"/"
- now selects an empty property (previously root-pointer)"a//b"
- is now a valid pointer to "a" » "" » "b"join
- no longer removes double slashes when joining join("/a/", "/b") » "/a//b"v5
- 2022/12/02 with , package has been renamed to json-pointer and published under @sagold/json-pointerv4
- 2020/11/09 with , pointer.delete has been renamed to remove`