Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the passed JSON Object #163

Open
EarthyOrange opened this issue Nov 8, 2021 · 9 comments
Open

Update the passed JSON Object #163

EarthyOrange opened this issue Nov 8, 2021 · 9 comments
Labels

Comments

@EarthyOrange
Copy link

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.

@brettz9
Copy link
Collaborator

brettz9 commented Nov 8, 2021

If you set the option resultType to all, you should be able to use parent and parentProperty to do this.

@EarthyOrange
Copy link
Author

@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.

@brettz9
Copy link
Collaborator

brettz9 commented Nov 12, 2021

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;
});

@CharlieGreenman
Copy link

@brettz9 this will not work recursively.

@CharlieGreenman
Copy link

I ended up using the json-pointer library in conjunction with pointer value to update json

@Yiniau
Copy link

Yiniau commented Apr 1, 2022

this way work for me

const fieldsSlot = jp({
  path: `$..children[?(@.children == "#[slot(\\"FIELDS\\"\\)\\]")]`,
  json: template,
})

fieldsSlot[0].children = fields.map(formFieldTransfer)

@EarthyOrange
Copy link
Author

@CharlieGreenman Thanks for the jsonpointer! Exactly what I was looking for.

@CharlieGreenman
Copy link

@CharlieGreenman Thanks for the jsonpointer! Exactly what I was looking for.

By all means

@rattrayalex
Copy link

rattrayalex commented Dec 27, 2022

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);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants