Javascript eval alternative for reading object [duplicate] - javascript

This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Closed 6 months ago.
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 ??

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'))

Related

Fetch data from json javascript [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
Here's my code:
{
"badge_sets":{
"1979-revolution_1":{
"versions":{
"1":{
"image_url":"https://static-cdn.jtvnw.net/badges/v1/7833bb6e-d20d-48ff-a58d-67fe827a4f84/1",
}
}
},
"60-seconds_1":{
"versions":{
"1":{
"image_url":"https://static-cdn.jtvnw.net/badges/v1/1e7252f9-7e80-4d3d-ae42-319f030cca99/1",
}
}
}
}}
Im trying to get something like that using javascript but currently i have no idea how to do it, Can someone help?
1979-revolution_1;https://static-cdn.jtvnw.net/badges/v1/7833bb6e-d20d-48ff-a58d-67fe827a4f84/1
60-seconds_1;https://static-cdn.jtvnw.net/badges/v1/1e7252f9-7e80-4d3d-ae42-319f030cca99/1
You can use ES6's Object.entries() so access the key and value of the nested badge_sets object. Remember that Object.entries() return a [key, value] tuple, so we can use argument destructuring to assign those variables.
The image URL can then be accessed using a combination of dot and bracket notation as such. Then, it is all about using ES6 template literal to put all the parts together to get the format you want.
Object.entries(data.badge_sets).map(([key, value]) => {
return `${key}:${value.versions['1'].image_url}`;
});
Note that this solution will return an array of formatted strings.
You can even take advantage of implicit returns from ES6's arrow function to have a one-liner, at the expense of readability (but looks nice!)
const formattedData = Object.entries(data.badge_sets).map(([key, value]) => `${key}:${value.versions['1'].image_url}`);
See proof-of-concept example:
const data = {
"badge_sets": {
"1979-revolution_1": {
"versions": {
"1": {
"image_url": "https://static-cdn.jtvnw.net/badges/v1/7833bb6e-d20d-48ff-a58d-67fe827a4f84/1",
}
}
},
"60-seconds_1": {
"versions": {
"1": {
"image_url": "https://static-cdn.jtvnw.net/badges/v1/1e7252f9-7e80-4d3d-ae42-319f030cca99/1",
}
}
}
}
};
const formattedData = Object.entries(data.badge_sets).map(([key, value]) => `${key}:${value.versions['1'].image_url}`);
console.log(formattedData);

State variable changes unpredictably - ReactJS [duplicate]

This question already has answers here:
Is this a good way to clone an object in ES6?
(10 answers)
What is the most efficient way to deep clone an object in JavaScript?
(67 answers)
Closed 2 years ago.
I am a newbie in React. I need some help to solve this issue
Code:
this.state={
testState: {
testArray: [
{ name: "bob" },
{ name: "alice" },
{ name: "john" }
]
}
}
testFn = () => {
let a;
a = { ...this.state.testState }; //using spread operator to copy the object instead of referencing
a.testArray.map((obj) => {
obj.name = "React is awesome"
})
console.log(this.state.testState)
}
Output:
testArray: Array(3)
0: {name: "React is awesome"}
1: {name: "React is awesome"}
2: {name: "React is awesome"}
I have to modify a without altering the state. But here, the state is also changed along with the iteration.
How can I solve this problem?
The spread operator only does a shallow copy
To guarantee a full object copy use
const copiedState = JSON.parse(JSON.stringify(yourState))
Better solution
Sove it at the source. Don't make deep state, its actually a key part of writing objects in the state. You should keep them very shallow. In this case you are already way deep with Obj -> Array -> Obj.

How do I dynamically get the values from Objects in Javascript? [duplicate]

This question already has answers here:
Convert a JavaScript string in dot notation into an object reference
(34 answers)
Closed 3 years ago.
So say that I have an array of objects with objects within the objects. This data is dynamic, i.e the keys wont be the same , it may differ.
For example:
[
{
"uuid": "53e7202c-28c8-4083-b910-a92c946a7626",
"extraIdentifiers": {
"National ID": "NAT2804"
},
"givenName": "Krishnan",
"customAttribute": null,
"age": "32"
},
{
"uuid": "9717ec58-8f87-4305-a57b-bed54301def7",
"extraIdentifiers": {
"National ID": "NAT2805"
},
"givenName": "Dale",
"customAttribute": null,
"age": "32"
},
{
"uuid": "d3563522-927d-4ff0-b697-eb164289a77d",
"extraIdentifiers": {
"National ID": "NAT2806"
},
"givenName": "David",
"age": "32"
}
]
Now I have a function which will get the value from one of the keys. For eg , I want to get the givenName so it will return David for example.
This is the code for it:
$scope.sortPatient = function (param) {
$scope.results.map(function (currentObj) {
console.log(currentObj[param]);
})
};
The $scope.results will hold the above JSON Obj. When calling sortPatient I would call it by passing the key whose value I want. For eg: sortPatient('givenName') or sortPatient('age').
This would log Dale or 32 in the console. But if I call sortPatient('extraIdentifiers.National ID') it does not log NAT2804 in the console, but logs undefined. I also tried calling it like sortPatient('extraIdentifiers[National ID]') but it still shows undefined.
How would I be able to get the values of keys inside keys? I also cannot change the way the function is being called. I can only change its definition., but I'm not able to get the values of keys inside complex objects.
I would pass an array with keys to your method instead, and then check if the object contains the given key path.
$scope.sortPatient = function (params) {
$scope.results.map(function (currentObj) {
var res = currentObj;
params.forEach(function(param){
if(res[param]) res = res[param];
})
console.log("res",res);
})
};
$scope.sortPatient(['extraIdentifiers','National ID']);

Retrieving JSON response data with dynamic key [duplicate]

This question already has answers here:
Accessing a JavaScript's object property without knowing that property name
(3 answers)
How to access the first property of a Javascript object?
(23 answers)
Getting the first index of an object
(14 answers)
Closed 3 years ago.
I'm calling an API in my application and need to drill down the JSON response. Within it there is a random string that changes so I can't hardcode the value. Is there a way I can access dataset1 no matter what the random string is?
{
"data": {
"Random String that Changes": {
"dataset1": {
"date": {...}
},
"dataset2":{
"date": {...}
}
}
},
"something else": {
...
},
"something else": {
...
}
}
Previously I was hard coding the drill down like such:
this.props.data.randomData['Random String that Changes'].dataset1.date
Also tried:
this.props.data.randomData[0].dataset1.date
You can get all the keys of the object using
const keys = Object.keys(this.props.data);
Now keys is an array of all keys , but if you json always only has 1 key, you can get your data using
this.props.data.randomData[keys[0]].dataset1.date
You can get dataset1
const values = Object.values(this.props.data)
console.log(values[0]['dataset1'])
Make sure that your json includes the "Random String that changes" at first place as shown in your above format.
Reference: Object.values
Try accessing the object like this :
const obj = this.props.data;
obj[Object.keys(obj)[0]].dataset1.date
Reference: How to access the first property of an object in Javascript?
Consider sample data in myObj.
var myObj = {
"data" : {
"Random String that Changes": {
"dataset1": {
"date": "123"
},
"dataset2":{
"date": "123"
}
}
}
}
var randomString =myObj[Object.keys(myObj)[0]];
var dataset1Date =randomString[Object.keys(randomString)[0]].dataset1.date;
console.log(dataset1Date);
So in this way you can access the date which you are trying with
this.props.data.randomData['Random String that Changes'].dataset1.date
Please check the below code for the solution.
var response = {
"data": {
"Random String that Changes": {
"dataset1": {
"date": {...}
},
"dataset2":{
"date": {...}
}
}
},
"something else": {
...
},
"something else": {
...
}
};
var dataInRandomKey = response.data[Object.keys(response.data)[0]];
Now, you have the whole JSON object (in current example, response['data']['Random String that Changes']) in dataInRandomKey variable.
You can try for in loop
var a = {
"data": {
"Random String that Changes": {
"dataset1": {
"date": {...}
},
"dataset2":{
"date": {...}
}
}
},
"something else": {
...
},
"something else": {
...
}
}
var response = a.data;
for(var key in response) {
console.log(response[key].dataset1);
}

Dynamically access object properties using a variable [duplicate]

This question already has answers here:
Accessing an object property with a dynamically-computed name
(19 answers)
Closed 4 years ago.
I have a large object with multiple objects nested within it. I have a function that will take the key of one of the objects, and I want to add a new property to the sub-object that is called. Something like https://jsfiddle.net/cf15xdfm/2/
var my_object = {
object1: {
key: 'value',
key2: 'value2'
},
object2: {
key: 'othervalue',
key2: 'another'
}
}
function doSomething(obj_key) {
// add a new property to the object
my_object.obj_key.new_prop = 'this_new_prop';
}
doSomething('object1');
console.dir(my_object);
How do I reference the variable obj_key in the doSomething method so that I can alter the desired object?
Make use of brackets notation for accessing dynamic keys
var my_object = {
object1: {
key: 'value',
key2: 'value2'
},
object2: {
key: 'othervalue',
key2: 'another'
}
}
function doSomething(obj_key) {
// add a new property to the object
my_object[obj_key].new_prop = 'this_new_prop'; // using bracket notation here
}
doSomething('object1');
console.dir(my_object);
You can use:
my_object[obj_key].new_prop='this_new_prop';
You can call properties as string like this:
obj['property_name']
So you should do this:
my_object[obj_key].new_prop = 'this_new_prop';
Edit: Sorry didn't see the answer was already there

Categories