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);
Related
This question already has answers here:
One liner to flatten nested object
(19 answers)
Closed 3 months ago.
good night, I'm having trouble merging an object inside another
my object currently.
{
"id":7,
"name":"Pedroo",
"email":"pedro#hotmail.com",
"cognitoSub":"9162b350-d19db1b3f",
"phoneNumber":"+5521997221764",
"photo":null,
"createdAt":"2022-10-21T14:48:36.000Z",
"updatedAt":"2022-10-21T14:48:36.000Z",
"Account":{
"userId":7
}
}
and I would like to leave it in a single object
example:
{
"id":7,
"name":"Pedroo",
"email":"pedro#hotmail.com",
"cognitoSub":"9162b350-d19db1b3f",
"phoneNumber":"+5521997221764",
"photo":null,
"createdAt":"2022-10-21T14:48:36.000Z",
"updatedAt":"2022-10-21T14:48:36.000Z",
"userId":7
}
Try this method
const flattenObj = (ob) => {
// The object which contains the
// final result
let result = {};
// loop through the object "ob"
for (const i in ob) {
// We check the type of the i using
// typeof() function and recursively
// call the function again
if ((typeof ob[i]) === 'object' && !Array.isArray(ob[i])) {
const temp = flattenObj(ob[i]);
for (const j in temp) {
// Store temp in result
result[j] = temp[j];
}
}
// Else store ob[i] in result directly
else {
result[i] = ob[i];
}
}
return result;
};
This question already has answers here:
Is it possible to implement dynamic getters/setters in JavaScript?
(5 answers)
Closed 3 years ago.
I have an object, let's call it obj, it looks like this:
const obj = {
key: "value"
}
Now I want to do something when a property is set. I heard about setters,
that I can use by doing:
const obj = {
set key(e) {
console.log("Property key has been set!")
}
}
But I want to do this, for any property... Like instead of only for key, it would be for anything, example:
obj.SomeKey = "value"
Should log "Property key has been set!"
and it would be the same for any property...
Is there a way in JavaScript to do this? Thanks
You could create a ES6 Proxy, which allows you to modify the set method like so:
const obj = {
key: "value"
};
const objProxy = new Proxy(obj, {
set: (obj, prop, v) => {
obj[prop] = v;
console.log("do something");
}
});
objProxy.name = "foo";
console.log(objProxy); // Proxy now has name attribute
console.log(obj); // And so does the original object
This question already has answers here:
How to use a variable for a key in a JavaScript object literal?
(16 answers)
Closed 5 years ago.
I have an object and I want to remove all values except the one that matches a particular key. For example, I could do this:
function remove(obj, key) {
var value = obj[key]
var ret = {}
ret[key] = obj[key]
obj = ret
}
Or I could iterate:
for (var k in obj) {
if (k != key) {
delete obj[k]
}
}
But I'm wondering if there's a better way. Creating a temporary variable and iterating over the entire object both seem unnecessary. My initial attempt was:
obj = {
key: obj[key]
}
But that resulted in an object with a key of key.
You can indeed achieve what you described without using temporary variables.
function remove(obj, key) {
return Object.assign({}, { [key] : obj[key]});
}
You can just create a new object with [key]:obj[key].
var obj = {
"a":1,
"b":2
};
var key = "a";
function filterByKey(object, key) {
return Object.create({[key]:obj[key]});
}
function filterByKey2(object, key) {
return {[key]:obj[key]};
}
console.log(filterByKey(obj, key));
console.log(filterByKey2(obj, key));
This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Test for existence of nested JavaScript object key
(64 answers)
Closed 6 years ago.
Considering this example:
if(this.plantService.plants[id])
{
if(this.plantService.plants[id].Name)
{
if(this.plantService.plants[id].Name[0])
return this.plantService.plants[id].Name[0].value;
else
return '';
}
else
return '';
}
return '';
I am wondering if it is possible to simplify what I am doing here.
My goal is to test the object-chain this.plantService.plants[id].Name[0] for validity.
However, if I just test if(this.plantService.plants[id].Name[0]) {...} exceptions are thrown.
Any proposals? :)
You could reduce the array with the object, after checking value and type.
function getIn(object, keys, def) {
return keys.reduce(function (o, k) {
return o && typeof o === 'object' && k in o ? o[k] : def;
}, object);
}
var object = { plantService: { plants: [{ Name: [{ value: 42 }] }] } };
console.log(getIn(object, ['plantService', 'plants', 0, 'Name', 0, 'value'], 'default value'));
console.log(getIn(object, ['b', 'c', 'd', 'e'], 'default value'));
You could write a simple function on your own like,
function getVal(obj, propQueue, defaultValue) {
for (var prop of propQueue) {
if ((obj = obj[prop]) === undefined) {
break;
}
}
return obj || defaultValue;
}
Now you can call it like,
var value = getVal(this, ["plantService", "plants", id, "name" 0], "");
console.log(value); //either "" or the real value.
You can try this:
if(this.plantService.plants[id] && this.plantService.plants[id].Name && this.plantService.plants[id].Name[0]){
return this.plantService.plants[id].Name[0].value;
}else{
return '';
}
Or maybe your problem is that your model is not complete and you need to be sure of that in order to prevent these validations and replace with this:
return this.plantService.plants[id].Name[0].value;
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;
}