Accessing nested JavaScript objects and arrays by string path
I just made this based on some similar code I already had, it appears to work:
Object.byString = function(o, s) {
s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
s = s.replace(/^\./, ''); // strip a leading dot
var a = s.split('.');
for (var i = 0, n = a.length; i < n; ++i) {
var k = a[i];
if (k in o) {
o = o[k];
} else {
return;
}
}
return o;
}
Usage::
Object.byString(someObj, 'part3[0].name');
See a working demo at http://jsfiddle.net/alnitak/hEsys/
EDIT some have noticed that this code will throw an error if passed a string where the left-most indexes don't correspond to a correctly nested entry within the object. This is a valid concern, but IMHO best addressed with a try / catch
block when calling, rather than having this function silently return undefined
for an invalid index.
Access a nested property with a string
You'll have to split the string by the period, and then access each node iteratively. This could be done in a simple reduce
:
var value = str.split('.').reduce(function(p,prop) { return p[prop] }, person);
The above would work regardless if str
contains a period or not, i.e. for name
as well as contact.phone
.
Set state value using string path key from deeply nested object
You can use the solution in here dynamically-set-property-of-nested-object in your handleChange method like this:
// set method copied from the above link
function set(obj, path, value) {
var schema = obj;
var pList = path.split('.');
var len = pList.length;
for(var i = 0; i < len-1; i++) {
var elem = pList[i];
if( !schema[elem] ) schema[elem] = {}
schema = schema[elem];
}
schema[pList[len-1]] = value;
}
...
const handleChange = (prop) => (e) => {
let value;
if (typeof e.target.value === "number") {
value = parseInt(e.target.value);
}
if (typeof e.target.value === "string") {
value = e.target.value;
}
setPayload((prevState) => {
const newState = {...prevState};
set(newState, prop, value);
return newState;
})
};
....
onChange={handleChange("downloadConfiguration.product.initialDownloadLength")}
Is there an easy way to use nested object > array key in string form?
You can use Lodash#get:
let someObject = {
nonProblematicValue: "all good",
arrayOfValues: ["can't touch this"]
}
let keyThatDoesNotWork = "arrayOfValues[0]"
console.log(_.get(someObject, keyThatDoesNotWork))
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
Accessing nested JavaScript objects and arrays by string path
I just made this based on some similar code I already had, it appears to work:
Object.byString = function(o, s) {
s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
s = s.replace(/^\./, ''); // strip a leading dot
var a = s.split('.');
for (var i = 0, n = a.length; i < n; ++i) {
var k = a[i];
if (k in o) {
o = o[k];
} else {
return;
}
}
return o;
}
Usage::
Object.byString(someObj, 'part3[0].name');
See a working demo at http://jsfiddle.net/alnitak/hEsys/
EDIT some have noticed that this code will throw an error if passed a string where the left-most indexes don't correspond to a correctly nested entry within the object. This is a valid concern, but IMHO best addressed with a try / catch
block when calling, rather than having this function silently return undefined
for an invalid index.
How to access a nested object with string paths?
Yes, but not with the syntax you've proposed. This is easiest done when your path is an array of strings:
const tableData = ( { profile: { firstname: 'jim', lastname: 'johnson' } }) const path = [ 'profile', 'firstname' ]
const valueAtPath = path.reduce((_, x) => _[x], tableData)
console.info(valueAtPath)
Access nested object dynamically by using array of string as a path
A simple approach would be to iterate the keyArray
and also keep traversing the object with keys from keyArray
function getNestedObject( keyArr ){
var tmp = parent; //assuming function has access to parent object here
keyArr.forEach( function(key){
tmp = tmp[key];
});
return tmp;
}
Demo
var parent = { type: { id: "2", label: "3", }};
function getNestedObject(keyArr) { var tmp = parent; //assuming function has access to parent object here keyArr.forEach(function(key) { tmp = tmp[key]; }); return tmp;}
console.log( getNestedObject( [ "type", "label" ] ) );
Related Topics
Setting CSS Pseudo-Class Rules from JavaScript
How to Dynamically Create CSS Class in JavaScript and Apply
How to Convert Unordered List into Nicely Styled ≪Select≫ Dropdown Using Jquery
How to Set Background Color of HTML Element Using CSS Properties in JavaScript
Jquery Counting Elements by Class - How to Implement This
How to Check If a Scrollbar Is Visible
Toggle Show/Hide Div With Button
How to Do Fade-In and Fade-Out With JavaScript and Css
Detect Change in Orientation Using JavaScript
How to Reload CSS Without Reloading the Page
Select All Div Text With Single Mouse Click
Jqgrid Does Not Render Correctly in Chrome/Chrome Frame
How to Change Style of Iframe Content Cross-Domain
Why Is It Bad Practice to Use Links With the JavaScript: "Protocol"
How to Change CSS Using Jquery