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
import{get,set,remove}from'@sagold/json-pointer';constdata={};get(data,'/path/to/nested/item');// undefinedset(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,removeandjoinalso accept a list of properties as pointer. Using join with a list of properties, its signature changes tojoin(properties:string[], isURI=false) -> string
get(data:object|array, pointer:string|array, defaultValue:any) -> value:any
returns nested values
importpointerfrom'@sagold/json-pointer';constdata={parent: {child: {title: 'title of child'}}}consttitleOfChild=pointer.get(data,'/parent/child/title');// output: 'title of child'console.log(pointer.get(data,'/parent/missing/path'));// output: undefinedand may optionally return a default value with
importpointerfrom'@sagold/json-pointer';constvalue=pointer.get({},"/invalid/value",42);console.log(value);// output: 42get also accepts a list of properties as pointer (e.g. split-result)
consttitleOfChild=pointer.get(data,['parent','child','title']);// output: 'title of child'console.log(pointer.get(data,['parent','missing','path']));// output: undefinedset(data:object|array, pointer:string|array, value:any) -> data:object|array
changes a nested value
importpointerfrom'@sagold/json-pointer';vardata={parent: {children: [{title: 'title of child'}]}};pointer.set(data,'/parent/children/1',{title: 'second child'});console.log(data.parent.children.length);// output: 2and may be used to build data
importpointerfrom'@sagold/json-pointer';constdata=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)
importpointerfrom'@sagold/json-pointer';constdata=pointer.set({},['list','[]','value'],42);console.log(data);// output: { list: [ { value: 42 } ] }set will create arrays when encountering a number
pointer.set({},['list','1','value'],42);// { list: [undefined, { value: 42 }] }alternatively you may use array-syntax [index]
pointer.set({},['list','[1]','value'],42);// { list: [undefined, { value: 42 }] }append items using empty array syntax []
pointer.set({list: [1,2]},['list','[]','value'],42);// { list: [1, 2, { value: 42 }] }create object using object syntax {index}
pointer.set({},['list','{1}','value'],42);// { list: { 1: { value: 42 }}
⚠️ setprefers existing data-type over specified data-types. For example: Setting an object for an existing array, will keep the object intact: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
importpointerfrom'@sagold/json-pointer';constdata=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)
importpointerfrom'@sagold/json-pointer';constdata=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
importpointerfrom'@sagold/json-pointer';constlist=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
importpointerfrom'@sagold/json-pointer';constdata={a: {b: true}};constlist=pointer.split('/a/b');console.log(pointer.get(data,list));// output: truesplitLast(pointer:string) -> [pointer, property]
separates json-pointers last property and returns both values as [parent-pointer, property]
importpointerfrom'@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
importpointerfrom'@sagold/json-pointer';constkey='my key';console.log(pointer.join('root',key,'/to/target'));// output: '/root/my key/to/target'and joins relative pointers as expected
importpointerfrom'@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
importpointerfrom'@sagold/json-pointer';constlist=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:
importpointerfrom'@sagold/json-pointer';constpath=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.
importpointerfrom'@sagold/json-pointer';// getconstvalue=pointer.get({'my value': true},'#/my%20value');console.log(value);// output: true// joinconstpointer=pointer.join('#/my value/to%20parent','../to~1child');console.log(pointer);// output: '#/my%20value/to~1child'// join an array of propertiesconsturiPointer=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
consturiPointer=pointer.join('my pointer','to','property',isURI=true);console.log(uriPointer);// output: '#/my%20pointer/to/property'consturiSimple=pointer.join('/my pointer/to/property',isURI=true);console.log(uriSimple);// output: '#/my%20pointer/to/property'constpointer=pointer.join('#/my pointer','to','property',isURI=false);console.log(pointer);// output: '/my pointer/to/property'- 2025/10/27
v7.2.0- changed exports to support esm
- 2025/01/14 with
v7pointer.setcreates arrays using numbers as properties/1when the data is null or an array (previously created objects)pointer.setcreates objects for numbers when using object-syntax/{1}(previously unsupported)
- 2024/04/06 with
v6, selection of empty properties is supported:"/"now selects an empty property (previously root-pointer)"a//b"is now a valid pointer to"a" » "" » "b"joinno longer removes double slashes when joiningjoin("/a/", "/b")»"/a//b"
- 2022/12/02 with
v5, package has been renamed tojson-pointerand published under@sagold/json-pointer - 2020/11/09 with
v4,pointer.deletehas been renamed toremove
