Open EarthyOrange opened 2 years ago
If you set the option resultType
to all
, you should be able to use parent
and parentProperty
to do this.
@brettz9 Can you please give me an example on how to use this API? I went through the ReadMe again but the usage isn't very clear to me.
Here's an example where we set all of the items with a price greater than 18 to having a price of 30.
const json = {
"store": {
"book": [{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}],
"bicycle": {
"color": "red",
"price": 19.95
}
}
};
JSONPath({
json,
path: '$..[?(@.price && @.price > 18)]',
resultType: 'all'
}).forEach(({parent, parentProperty}) => {
// `parent` and `parentProperty` used together get us to the object which our
// path has matched, but we also need to specify the `price` property since we
// don't want to overwrite the whole object--only the object's `price`.
parent[parentProperty].price = 30;
});
@brettz9 this will not work recursively.
I ended up using the json-pointer library in conjunction with pointer value to update json
this way work for me
const fieldsSlot = jp({
path: `$..children[?(@.children == "#[slot(\\"FIELDS\\"\\)\\]")]`,
json: template,
})
fieldsSlot[0].children = fields.map(formFieldTransfer)
@CharlieGreenman Thanks for the jsonpointer
! Exactly what I was looking for.
@CharlieGreenman Thanks for the
jsonpointer
! Exactly what I was looking for.
By all means
Can't you do this?
const result = JSONPath({
json,
path: '$..[?(@.price && @.price > 18)]',
resultType: 'all'
callback: (value, _, { parent, parentProperty }) => {
parent[parentProperty].price = 30
},
})
of course, you could wrap this in a nice little helper:
const result = JSONPath({
json,
path: '$..[?(@.price && @.price > 18)].price',
resultType: 'all'
callback: updater(value => 30),
})
const updater = (cb) => (value, _, { parent, parentProperty }) => {
return parent[parentProperty] = cb(value);
}
Motivation
Updating the passed JSON object
Current behavior
I don't think it exists
Desired behavior
JSONPath({ path: '..', json: {}, newValue: 'new' });
should update the json object with the new value at the location specified by the path.