0

I am trying to read values from JSON Object using a function that is dynamic.

Sample JSON Object -

var test = 
{
  "test1": {
    "test2": "value2"
  },
  "test3": {
    "test4": {
      "test5": "value5"
    }
  }
}

Now I need to read the test5 value and test2 value so I created the below method and called it twice by passing the argument.

readValue('test1.test2');
readValue('test3.test4.test5');

function readValue(val){
  console.log(eval(`test.${val}`));
}

This code is working fine, I am able to get the output.

But is there any alternative to use eval here ??

Ashish Mishra
  • 145
  • 3
  • 13
  • You don't need any of that. You can simply access `test.test1.test2.value2`, for example. In fact, adding double quotes on the object keys is really only necessary when saved in a JSON file (if you wanna be able to parse that file at some point). In JS code (unlike Python BTW), you may as well omit all of those double quotes on the keys. And again, regardless of whether or not you use them, you can simply access the object values using dots (as shown above). –  Sep 07 '22 at 10:49
  • Why aren't you splitting your val? Like `val.split('.')` and then read per recursion? – Felix Sep 07 '22 at 10:49
  • There's not a thing like a JSON object. Anyway you can check this solution: https://stackoverflow.com/a/43849204/1850851 – Christian Vincenzo Traina Sep 07 '22 at 10:53
  • I am able to access via dots, but the problem is i am trying to generify the method to access the object. – Ashish Mishra Sep 07 '22 at 14:32

1 Answers1

1

Better than eval, split your compound key by a dot and iterate it:

let val = (obj, keys) => keys.split('.').reduce(Reflect.get, obj)

var test = 
{
  "test1": {
    "test2": "value2"
  },
  "test3": {
    "test4": {
      "test5": "value5"
    }
  }
}

console.log(val(test, 'test1.test2'))
console.log(val(test, 'test3.test4.test5'))
gog
  • 10,367
  • 2
  • 24
  • 38
  • Even if it works, the use of `Reflect.get` in that way is pretty weird. `reduce` provides 3 parameters, and also [`Reflect.get`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/get#syntax) accepts 3 parameters. The third parameter is the reference to `this`, this makes me think that using proxies or function references it may break – Christian Vincenzo Traina Sep 07 '22 at 10:58
  • @ChristianVincenzoTraina: yep, yet another example of senseless overengineering, which is archetypical in javascript. – gog Sep 07 '22 at 11:36
  • Yes, but as a rule of thumb, it's better to avoid using function references in place of callbacks, it's always safer to use `(a, b) => Reflect.get(a, b)`, in this way we're sure we're passing exactly two parameters – Christian Vincenzo Traina Sep 07 '22 at 12:13