Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
9
rated 0 times [  12] [ 3]  / answers: 1 / hits: 39141  / 7 Years ago, thu, june 22, 2017, 12:00:00

Sorry for any confusion. To put simply I want to make several titles with unordered lists.



<h3>level_3 key title</h3>
<ul>
<li>level_4 value</li>
<li>level_4 value</li>
</ul>

<h3> another level_3 key title</h3>
<ul>
<li>level_4 value</li>
<li>level_4 value</li>
</ul>


Difficult to phrase the problem into a question. Essentially having a really hard time trying to parse through some JSON and display the data correctly. What I would like to do is display level_3.x below as a top level list item and the nested level_4.x as nested list items. To be clear using React



Example:




  • KEY from level_3.1


    • String from level_4.1

    • String from level_4.2




Repeat for every level_3.x object



Example Data



level_1:{
level_2.1:{
level_3.1:{
level_4.1:[string,string,string],
level_4.2:[string,string,string]
}
level_3.2:{
level_4.1:[string,string,string],
level_4.2:[string,string,string]
}
}
level_2.2:{
level_3.1:{
... Same as above
}
level_3.2:{
... Same as above
}
}
}


What I have done since you can only map an array, from my understanding, is try and go through level_3.x and push those to an Array. I can map over that and display the items as expected.



Parent Component



render(){
return( <Child heading=A data={resource.data} /> )
}


Child Component



render(){
let groupObj;
let groupArray;
let subListItems;

if('value' in this.props.data){
var i;
for(i = 0; i < Object.keys(groupObj).length; i++){
groupArray.push(Object.keys(groupObj)[i] + , + Object.values(groupObj)[i])
// Have removed the Object.values because I was trying to make everything flat and pull out the first item. Leaving it in because that was my original direction in the case it was actually the right way to go
}
}
listItems = groupArray.map((item, index)=>(<li key={index}>{item}</li>));

return({listItems})
}


Thus far I can produce:




  • level_3.1

  • level_3.2



console log > [level_3.1,level_3.2]



Which is great, and halfway there. Now where things break down is I can't seem to figure out how to get the level_4.x elements to render.



I tried writing another map function inside the previous:



listItems = groupArray.map((item, index) => (
<li key={index}>
{item}
<ul>
{subListItems = groupObj.item.map((subItem, index) => (
<li key={index+1}>{subItem}</li>
))};
</ul>
</li>
));


This returns a map of undefined error, however if item is replaced with a key it'll work. groupObj.level_4.1.map() That will return a level_4.1 values:




  • level_3.1


    • level_4.1 value

    • level_4.1 value << unable to map level_4.2 and using item from the parent map function will return undefined




So either doing this completely wrong, or missing a way to pass in a dynamic value into that groupObj.[needs to be dynamic based on parent].map()



Note, do know that using index as a key value is an anti-pattern just have that in for sake of getting this to work.



Update



Feel like this is 90% there but having one last issue. Took both answers into consideration and the easiest for me to implement and understand what I'm typing at this time is the following:



render(){

let listItems;
let name = this.props.heading

if('level_2' in this.props.data){

let data = this.props.data.level_2[name];
console.log('ok we can get to work', data); // <<< Good

listItems = Object.keys(data).map((propKey) => (
<ul key={propKey}>
{propKey} // <<< Good
{console.log('PROP KEY', propKey)} // <<< Good
{data[propKey].map((childPropKey) =>{
<li key={childPropKey}>
{childPropKey} // <<<<<< PROBLEM, This returns nothing in the DOM
{console.log(childPropKey)} // <<< Good
</li>
})}
</ul>
));

return(<div>{listItems}</div>)
}


So I'm able to console.log(childPropKey) and return expected results. But just trying to return {childPropKey} nothing gets returned



Working ES5



listItems = Object.keys(data).map(function(propKey){
return <ul key={propKey}>
{propKey}
{data[propKey].map(function(childPropKey){
return <li key={childPropKey}>
{childPropKey}
</li>
})}
</ul>
});


Working ES6



listItems = Object.keys(data).map((propKey) => (
<ul key={propKey}>
{propKey}
{data[propKey].map((childPropKey) =>(
<li key={childPropKey}>
{childPropKey}
</li>
))}
</ul>
));

More From » arrays

 Answers
9

Instead of trying to convert the object into an array, just cut that out and loop directly through the Object.keys array.



render () (
<ul>
{Object.keys(this.props.data).map((propKey) => {
<li key={propKey}>
{this.props.data[propKey]}

<ul>
{Object.keys(this.props.data[propKey]).map((childPropKey) => {
<li key={childPropKey}>
{this.props.data[propKey][childPropKey]}
</li>
})}
</ul>
</li>
})}
</ul>
);


I've made some assumptions on your data structure, so hopefully you can translate it to your implementation.


[#57341] Tuesday, June 20, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
xavier

Total Points: 711
Total Questions: 91
Total Answers: 121

Location: Gabon
Member since Sat, Jul 25, 2020
4 Years ago
;