Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
154
rated 0 times [  159] [ 5]  / answers: 1 / hits: 48319  / 7 Years ago, mon, january 8, 2018, 12:00:00

I am new to react and trying to implement all the key and values of a JSON object in my web page. I have a below JSON structure. I want all the keys and values to be printed in my web page where key should be printed as labels.



{
key1: value1,
key2: value2,
key3: value3,
key4:{
k1: val1,
k2: {
p1: v1,
p2: v2,
p3: v3
}
}
}


I have written the below code to get the keys and values of this JSON.



getValues() {
let arr = [];
arr = Object.keys(this.props.myArr).map(key =>
<div key={this.props.data[key]} className=row>
<div className=col-xs-6>{key}</div>
<div className=col-xs-6>{this.props.myArr[key]}
</div>
</div>

)
return arr;
}
render() {
return (
<div>
<Header />
<div className=content>
{this.getValues()}
</div>
</div>
)
}


}



props.myArr has the entire object.



I am able to print the keys and values but not the nested object under key4(p1,p2,p3). I want all the keys along with its values to be printed one after another in my web page. Can someone tell me where am i going wrong and how to access all the keys (as labels) and values of the JSON object.



Edited-



const myObj = {
key1: value1,
key2: value2,
key3: value3,
key4: {
k1: val1,
k2: {
p1: v1,
p2: v2,
p3: v3
}
}
}


class Details extends React.component{
constructor(){
this.getValues = this.getValues.bind(this);
}
getValues() {
let arr = [];
arr = Object.keys(myObj).map(key =>
<div key={myObj[key]} className=row>
<div className=col-xs-6>{key}</div>
<div className=col-xs-6>{myObj[key]}
</div>
</div>

)
return arr;
}

generateData(myObj) {

const newData = Object.keys(myObj).reduce((result, currentKey) => {
if (typeof myObj[currentKey] === 'string' || myObj[currentKey] instanceof String) {
const elementToPush = getValues(currentKey, myObj[currentKey]);
result.push(elementToPush);
} else {
const nested = generateData(myObj[currentKey]);
result.push(...nested);
}
return result;
}, []);
return newData;
}

render() {
return (
<div>
<Header />
<div className=content>
{this.generateData(myObj)}
</div>
</div>
)
}
}


}



P.S I am using getValues with map function to retrieve first level of key and values as the provided syntax by you under generateElement() gives me error.


More From » json

 Answers
10

What you need here is recursion.



Though, there is something missing in your design, you are not defining the exact condition for when should the program actually extract the value.



For example, lets define that if a value of a given key is a string, then we will render it to the page.



Such condition will look something like this:



if (typeof data[key] === 'string' || data[key] instanceof String)


Then with this decision, you can write a function that will take a data object and recursively will go over the object's keys, based on the condition above, it will return the value Or another call to the same function with the value as the new data object.



The function will look something along this block of code:



function generateData(data) {
const newData = Object.keys(data).reduce((result, currentKey) => {
if (typeof data[currentKey] === 'string' || data[currentKey] instanceof String) {
result.push(currentKey);
} else {
const nested = generateData(data[currentKey]);
result.push(...nested);
}
return result;
}, []);
return newData;
}


I'm using .reduce here to build a new array. and as mentioned above, i will push to the new array either the key or the result of a recursive call to the function with the value as the new data object, of course based on the condition mentioned above.

Note, that the recursive call will return an array, so i'm using the spread syntax to extract it's members.



Now, we want our key and value to get rendered to the DOM.

So instead to just push the key or value, we can push an element.



Here is a full running example:





const myData = {
key1: value1,
key2: value2,
key3: value3,
key4: {
k1: val1,
k2: {
p1: v1,
p2: v2,
p3: v3
}
}
}

const generateElement = (key,value) => {
return (
<div key={key} className=row>
<div className=col-xs-6 ins-label>{key}</div>
<div className=col-xs-6>{value}</div>
</div>
);
}

function generateData(data) {
const newData = Object.keys(data).reduce((result, currentKey) => {
if (typeof data[currentKey] === 'string' || data[currentKey] instanceof String) {
const elementToPush = generateElement(currentKey, data[currentKey]);
result.push(elementToPush);
} else {
const nested = generateData(data[currentKey]);
result.push(...nested);
}
return result;
}, []);
return newData;
}

class App extends React.Component {
render() {
const { data } = this.props;
return (
<div>
{generateData(data)}
</div>
)
}
}

ReactDOM.render(<App data={myData} />, document.getElementById('root'));

<link href=https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css rel=stylesheet/>
<script src=https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js></script>
<script src=https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js></script>
<div id=root></div>




[#55511] Friday, January 5, 2018, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
brendan

Total Points: 426
Total Questions: 110
Total Answers: 94

Location: Western Sahara
Member since Mon, May 3, 2021
3 Years ago
;