The following function does an amazing job of retrieving a deep object key value with a dot notated string:
function getPathValue(obj, path) {
return new Function('_', 'return _.' + path)(obj);
}
For example, it returns the value for a key like "bar" using the following as the path argument:
'data.abc.foo.bar'
However, some API's pack additional stringified JSON into some key values.
I'm looking for an enhancement to the above function that will handle that case.
For example, Stack's own WebSocket service:
wss://qa.sockets.stackexchange.com/
returns strings like this:
{"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"stackoverflow.com\",\"id\":53819390,\"titleEncodedFancy\":\"Should I start with webGL1 or webGL2 when using Three.js\",\"bodySummary\":\"Spent some time learning and understanding the basics of webGL and I'm now diving into Three.js.\\n\\nI noticed that I have the option of using webGL1 or webGL2. Seems as if webGL1 is the default, however ...\",\"tags\":[\"three.js\",\"webgl\"],\"lastActivityDate\":1545064508,\"url\":\"https://stackoverflow.com/questions/53819390/should-i-start-with-webgl1-or-webgl2-when-using-three-js\",\"ownerUrl\":\"https://stackoverflow.com/users/8226111/romanrogers\",\"ownerDisplayName\":\"romanrogers\",\"apiSiteParameter\":\"stackoverflow\"}"}
And I'd like to be able to use the above function to retrieve values with an input string like:
'data.bodySummary'
Perhaps the input string could look something like:
'data/bodySummary'
where the solidus (/slash) represents a JSON.parse().
Note, this needs to be dynamic as I'd like to make it where the end user can select arbitrary keys to return values for in the general case.
You could check if the item from where you take a property is a string an perform a parsing. The return the value of the property.
function getValue(object, path) {
return path
.split('.')
.reduce((o, k) => (typeof o === 'string' ? JSON.parse(o) : o)[k], object);
}
var data = {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"stackoverflow.com\",\"id\":53819390,\"titleEncodedFancy\":\"Should I start with webGL1 or webGL2 when using Three.js\",\"bodySummary\":\"Spent some time learning and understanding the basics of webGL and I'm now diving into Three.js.\\n\\nI noticed that I have the option of using webGL1 or webGL2. Seems as if webGL1 is the default, however ...\",\"tags\":[\"three.js\",\"webgl\"],\"lastActivityDate\":1545064508,\"url\":\"https://stackoverflow.com/questions/53819390/should-i-start-with-webgl1-or-webgl2-when-using-three-js\",\"ownerUrl\":\"https://stackoverflow.com/users/8226111/romanrogers\",\"ownerDisplayName\":\"romanrogers\",\"apiSiteParameter\":\"stackoverflow\"}"};
console.log(getValue(data, 'data.bodySummary'));
ES5
function getValue(object, path) {
return path
.split('.')
.reduce(function (o, k) {
return (typeof o === 'string' ? JSON.parse(o) : o)[k];
}, object);
}
var data = {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"stackoverflow.com\",\"id\":53819390,\"titleEncodedFancy\":\"Should I start with webGL1 or webGL2 when using Three.js\",\"bodySummary\":\"Spent some time learning and understanding the basics of webGL and I'm now diving into Three.js.\\n\\nI noticed that I have the option of using webGL1 or webGL2. Seems as if webGL1 is the default, however ...\",\"tags\":[\"three.js\",\"webgl\"],\"lastActivityDate\":1545064508,\"url\":\"https://stackoverflow.com/questions/53819390/should-i-start-with-webgl1-or-webgl2-when-using-three-js\",\"ownerUrl\":\"https://stackoverflow.com/users/8226111/romanrogers\",\"ownerDisplayName\":\"romanrogers\",\"apiSiteParameter\":\"stackoverflow\"}"};
console.log(getValue(data, 'data.bodySummary'));