jsonpath-object-transform icon indicating copy to clipboard operation
jsonpath-object-transform copied to clipboard

Using jsonpath filtering on arrays breaks sub-templates

Open dremekie opened this issue 8 years ago • 2 comments

Hi. Thanks for this helpful library.

Please see the following 3 code snippets. The second version fails. I am trying to apply a sub-template transformation to a filtered (via jsonpath notation) array and it fails. Without the filter, it works.

var transform = require('jsonpath-object-transform');

var o = {"cities": [
    {"city": "Toronto", "population": 2.5},
    {"city": "New York", "population":8.1},
    {"city": "San Diego", "population": 1.6},
    {"city": "Seattle", "population": 0.65}
]};

// works
var template = {
    bigCities: ["$.cities[?(@.population > 2)]"]
};

var r = transform(o, template);
console.log(JSON.stringify(r, null, 4));

Results in:

{
    "bigCities": [
        {
            "city": "Toronto",
            "population": 2.5
        },
        {
            "city": "New York",
            "population": 8.1
        }
    ]
}
var transform = require('jsonpath-object-transform');

var o = {"cities": [
    {"city": "Toronto", "population": 2.5},
    {"city": "New York", "population":8.1},
    {"city": "San Diego", "population": 1.6},
    {"city": "Seattle", "population": 0.65}
]};

// fails
var template = {
    bigCities: ["$.cities[?(@.population > 2)]", {"name": "city"}]
};

var r = transform(o, template);
console.log(JSON.stringify(r, null, 4));

results in

TypeError: seek[0].forEach is not a function
    at seekArray (/Users/dwayne/tmp/test/node_modules/jsonpath-object-transform/lib/jsonpath-object-transform.js:96:15)
    at walk (/Users/dwayne/tmp/test/node_modules/jsonpath-object-transform/lib/jsonpath-object-transform.js:52:7)
    at /Users/dwayne/tmp/test/node_modules/jsonpath-object-transform/lib/jsonpath-object-transform.js:118:7
    at Array.forEach (native)
    at seekObject (/Users/dwayne/tmp/test/node_modules/jsonpath-object-transform/lib/jsonpath-object-transform.js:117:26)
    at walk (/Users/dwayne/tmp/test/node_modules/jsonpath-object-transform/lib/jsonpath-object-transform.js:52:7)
    at /Users/dwayne/tmp/test/node_modules/jsonpath-object-transform/lib/jsonpath-object-transform.js:131:5
    at Object.<anonymous> (/Users/dwayne/tmp/test/json-transform.js:17:9)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
var transform = require('jsonpath-object-transform');

var o = {"cities": [
    {"city": "Toronto", "population": 2.5},
    {"city": "New York", "population":8.1},
    {"city": "San Diego", "population": 1.6},
    {"city": "Seattle", "population": 0.65}
]};

// works
var template = {
    bigCities: ["$.cities", {"name": "city"}]
};

var r = transform(o, template);
console.log(JSON.stringify(r, null, 4));

results in

{
    "bigCities": [
        {
            "name": "Toronto"
        },
        {
            "name": "New York"
        },
        {
            "name": "San Diego"
        },
        {
            "name": "Seattle"
        }
    ]
}

dremekie avatar May 27 '16 18:05 dremekie

this issue can be resolved by auto-wrapping the seek result if the length is > 1 and a subpath exists.

https://github.com/conscia/jsonpath-object-transform/commit/e93f105fef0a7478bbc0f5f55f9bdf8fa747d7cd

ferronrsmith avatar Jun 20 '16 06:06 ferronrsmith

@ferronrsmith can you show how you would have done this? I have the same problem, but struggling with the exact syntax.

Thanks a lot man

Rendiere avatar Feb 22 '17 10:02 Rendiere