This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Closed 7 years ago.
I have an object:
{
messages: {
foo: {
bar: "hello"
},
other: {
world: "abc"
}
}
}
I need a function:
var result = myFunction('messages.foo.bar'); // hello
How to create this function?
Thanks
I've written such a set of utility functions here:
https://github.com/forms-js/forms-js/blob/master/source/utils/flatten.ts
There's also the Flat library:
https://github.com/hughsk/flat
Either should suit your needs. Essentially it boils down to something like this:
function read(key, object) {
var keys = key.split(/[\.\[\]]/);
while (keys.length > 0) {
var key = keys.shift();
// Keys after array will be empty
if (!key) {
continue;
}
// Convert array indices from strings ('0') to integers (0)
if (key.match(/^[0-9]+$/)) {
key = parseInt(key);
}
// Short-circuit if the path being read doesn't exist
if (!object.hasOwnProperty(key)) {
return undefined;
}
object = object[key];
}
return object;
}
Related
This question already has answers here:
Why can I not use the spread operator on a class function?
(3 answers)
Copy prototype for inheritance?
(2 answers)
Closed 25 days ago.
Alright, I must be missing something here. I have an object:
export class Country {
id: number = 0
name: string = ''
getNamePlusBob() {
return this.name + 'bob'
}
}
And I get the data from an API in an array, then pass it to the browser.
Once i have the data I want to turn the array into an array of objects of type 'Country'.
So I made this function (not sure if Hydrate is the correct term here?):
function hydrateArray(data, entity) {
let returnArray = []
console.log(data)
data.forEach((row) => {
const object = entity;
for (const [key, value] of Object.entries(row)) {
if(Object.hasOwn(object, key)) {
object[key] = value
} else {
console.log('Key not found in entity', key)
}
}
console.log(object.getNamePlusBob())
returnArray.push({...object})
})
return returnArray
}
const countries = hydrateArray(countryData, new Country())
In the console.log in the function, I can run the getNamePlusBob() and it returns the name plus bob. However, on the returned array countries, I cannot:
console.log(countries[0].getNamePlusBob())
TypeError: countries[0].getNamePlusBob is not a function
Why not? It was inside the hydrateArray function, why cant I run it outside?
This question already has answers here:
How to set object property (of object property of..) given its string name in JavaScript?
(16 answers)
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Dynamically set property of nested object
(28 answers)
Convert a JavaScript string in dot notation into an object reference
(34 answers)
Closed 2 years ago.
Below is my json content
{
"demoPO":{
"login":["demoJPLog in", "demoFRLog in","GELog in"],
"cancel":["demoJPCancel", "demoFRcancelo","GEcancelo"],
"content":["demoJPcontent", "demoFRcontent","GEcontent"]
},
"demoPO2":{
"login":["JPLog in", "FRLog in","GELog in"],
"cancel":["JPCancel", "FRcancelo","GEcancelo"],
"content":["JPcontent", "FRcontent","GEcontent"],
"submit":["JPsubmit", "FRsubmit","GEsubmit"]
}
}
I want to update value of key demPO2.login[0]
data.demoPO2.login[0] = value; //this updates key - works
consider user is passing **key** as a variable
var keyName = 'demPO2.login[0]'
data[keyname] = value; //doesn't update, adds a new one
Is there a way to overcome this where user can pass key as variable and update when there are multi-level array in json?
You can use lodash _.set method.
import _ from "lodash";
_.set(data, "demoPO2.login[0]", "test1");
You should extract path to element from key to be ["demPO2", "login", "0"], and then loop it:
var json = {
"demoPO":{
"login":["demoJPLog in", "demoFRLog in","GELog in"],
"cancel":["demoJPCancel", "demoFRcancelo","GEcancelo"],
"content":["demoJPcontent", "demoFRcontent","GEcontent"]
},
"demoPO2":{
"login":["JPLog in", "FRLog in","GELog in"],
"cancel":["JPCancel", "FRcancelo","GEcancelo"],
"content":["JPcontent", "FRcontent","GEcontent"],
"submit":["JPsubmit", "FRsubmit","GEsubmit"]
}
};
function extract(key) {
var keys = key.split('.');
var current = json;
for (var i = 0; i < keys.length; i++) {
if (typeof current[keys[i]] === 'undefined') {
return null;
}
current = current[keys[i]];
}
return current;
}
// For simplicity we assume key is `.` separated
console.log(extract('demoPO2.login.0'));
console.log(extract('demoPO2.content.2'));
console.log(extract('demoPO2.key.notExists'));
This question already has answers here:
How to store a javascript function in JSON
(7 answers)
Closed 3 years ago.
So I have a js object with the following sample key-value pairs.
var serial = {
open: function(a, b) {
do something..
},
close: function (a,b) {
do something
}
}
As seen above the value for the keys are js functions. Due to some requirements I had to convert the whole object to string. I had used the following code to convert it to string:
var json = JSON.stringify(window.serial, function(key, value) {
if (typeof value === 'function') {
return value.toString();
} else {
return value;
}
});
How can I convert the strings back to function prototypes and store it in the same obj?
eval will convert string back to function
var str = "function fn(){ console.log('loggin function') }";
eval(str);
fn();
This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Fastest way to flatten / un-flatten nested JavaScript objects
(17 answers)
Closed 3 years ago.
Let's say I have object like this:
let object = {
inner: {
inInner: {
a: 5
}
}
}
and I want to store path to property a in variable so I can access it like this:
object[pathToProperty]
Thank you for any suggestions
You can import Lodash, and use it like this:
var path = 'inner.inInner';
var value = _.get(object, path);
You could take a Proxy and address the inner key.
let object = { inner: { inInner: { a: 5 } } },
proxy = new Proxy(object, {
find: function (o, k) {
var value;
if (k in o) return o[k];
Object.values(o).some(v => {
if (v && typeof v === 'object') {
return value = this.find(v, k);
}
});
return value;
},
get: function(obj, prop) {
return prop in obj ?
obj[prop] :
this.find(obj, prop);
}
});
console.log(proxy.a);
This question already has answers here:
Convert string in dot notation to get the object reference [duplicate]
(6 answers)
Closed 8 years ago.
I would like to split the str (dot seperated) and look inside an object tree, if the values exist.
To keep it simple, I have just create a simple object, but I would like it to be a deep search.
I just need the logic not necessary a working code, just a direction on what I need to do inside the exists to, check recursebly if person.name.first does exist with a boolean value true || false to be returned as the final answer.
var str = "person.name.first";
var arr = {
person: {
name: {'first':true ,'last' : true },
age : true
}
}
function exists(){
...
}
exists(str,arr);//true === exists, false === does not exist
Just try with:
function exists(str, arr) {
var parts = str.split('.');
for (var i = 0; i < parts.length; i++ ) {
if (arr.hasOwnProperty(parts[i])) {
arr = arr[parts[i]];
} else {
return false;
}
}
return true;
}