You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
wrap option returns the same result for arrays whether true or false #86
JSONPath returns the same result for the following 2 queries: JSONPath({data: data, path: "$.store.book", wrap: true}); JSONPath({data: data, path: "$.store.book", wrap: false});
[[{"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}]]
I believe for wrap: false, the outer array should be removed like this:
[{"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}]
If wrap is true (the current default), return an empty array.
If wrap is false, return undefined.
When a single non-array result is found:
If wrap is true (the current default), follow case 3 .
If wrap is false, return the item as is.
When more than one result or an array is found, return the results within an array (regardless of wrap).
Thus if you get array results with wrap: false, you know you either grabbed an array or got multiple results and can just use the results as is, without any unwrapping. You know with undefined that nothing was found, and if you got a scalar, that that was the single value.
A better naming for this alternative wrap: false (and I think preferable) behavior might be unwrap: true.
Perhaps we could add an option that avoids breaking existing code and follows the behavior you describe (of unwrapping arrays as well): wrap: 'never'.
And perhaps we should also add an option of wrap: 'found' with this behavior:
When no results are found, return undefined.
For any other case, return the results wrapped within an array
This approach would have the benefit over wrap: false of allowing a single approach with non-array or array results and single or multiple results. It would also have the benefit over wrap: false (and wrap: true) of being able to distinguish between finding the result undefined and not finding any result.
Point 3 above about how wrap has worked doesn't match what I am seeing; I see an array where the first item is also an array (the one result)...ending up with a multidimensional array is odd and don't think unwrapping the result array is anyway required, if you're using an expression with the expectation of getting an array then you do whatever you need to with the returned result in your own code doesn't seem like the responsibility of this library.
Ideally wrap: false should be consistent in that it returns the result (if single match); if you are going to change the data type of wrap anyway then it is already a breaking change so why not avoid the confusion of what the different wrap values mean and just keep it as boolean with predictable behaviour.
A more accurate summary of current behavior for wrap: false than my earlier statement is as follows:
No matches: return undefined
One match that did not come through an array-expression operator (for example filter, wildcard, slice, union, or recursive descent): return the value directly.
Otherwise: return an array
I propose a new option—one which preserves backward compatibility: collapseSingleMatch. This will throw if it is not used with wrap: false.
When enabled, it will make single-match behavior consistent by returning the value directly for any single match, regardless of path shape.
Activity
brettz9 commentedon Oct 20, 2018
This would be the more intuitive behavior.
However,
wraphas worked as follows...wrapistrue(the current default), return an empty array.wrapisfalse, returnundefined.wrapistrue(the current default), follow case 3 .wrapisfalse, return the item as is.wrap).Thus if you get array results with
wrap: false, you know you either grabbed an array or got multiple results and can just use the results as is, without any unwrapping. You know withundefinedthat nothing was found, and if you got a scalar, that that was the single value.A better naming for this alternative
wrap: false(and I think preferable) behavior might beunwrap: true.Perhaps we could add an option that avoids breaking existing code and follows the behavior you describe (of unwrapping arrays as well):
wrap: 'never'.And perhaps we should also add an option of
wrap: 'found'with this behavior:undefined.This approach would have the benefit over
wrap: falseof allowing a single approach with non-array or array results and single or multiple results. It would also have the benefit overwrap: false(andwrap: true) of being able to distinguish between finding the resultundefinedand not finding any result.(Note the responsible code to change is at https://github.com/s3u/JSONPath/blob/master/src/jsonpath.js#L202-L214 , esp. 203-205)
richturner commentedon Oct 4, 2019
Just my thoughts/observations...
Point 3 above about how
wraphas worked doesn't match what I am seeing; I see an array where the first item is also an array (the one result)...ending up with a multidimensional array is odd and don't think unwrapping the result array is anyway required, if you're using an expression with the expectation of getting an array then you do whatever you need to with the returned result in your own code doesn't seem like the responsibility of this library.Ideally
wrap: falseshould be consistent in that it returns the result (if single match); if you are going to change the data type ofwrapanyway then it is already a breaking change so why not avoid the confusion of what the different wrap values mean and just keep it asbooleanwith predictable behaviour.brettz9 commentedon Oct 5, 2019
Thanks for your comments. I'll give this some more thought if I'm revisiting this, but tbh, this library is a low priority for me atm.
brettz9 commentedon Aug 7, 2026
A more accurate summary of current behavior for
wrap: falsethan my earlier statement is as follows:I propose a new option—one which preserves backward compatibility:
collapseSingleMatch. This will throw if it is not used withwrap: false.When enabled, it will make single-match behavior consistent by returning the value directly for any single match, regardless of path shape.
Sound good?