Applying functions to parts of data in a promise chain using JSONPath
When working with promise chains, you sometimes pipe through a bit more complex data than just a value, and would like to apply a pipeline stage to just subparts of that complex data. I used to have a function that did just that in python, but now it is time for javascript!
Here is one way of doing that in javascript that I just came up with. First what it looks like in practice, here we're are calling an uppercase transformation on just part of the data structure being passed through:
.then(forPaths('$..author', uppity)).then(
The above uppercases the value of any property named "author". With JSON path syntax we could have selected other parts too.
We are using a library called JSONPath to specify what parts of the data structure we would like to apply the function too. Here is a complete working example, using an example data structure from JSONPath's documentation:
const jp = require('jsonpath') // Here is the general function for applying anything to any // part of a data structure going through a promise chain. // It is curried, so the data comes first when the pipeline is executed: const forPaths = (pathExpr, fun) => data => { jp.apply(data, pathExpr, fun) return data } // some test data, taken from the docs for JSONPath: var data = { "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 } } } // An example function for doing some kind of transformation, in this case convert to uppercase const uppity = text=>text.toUpperCase() // Finally, an example promise chain: Promise.resolve(data).then(forPaths('$..author', uppity)).then(JSON.stringify).then(console.log)