I'm just getting started with React and am trying to loop through an object that is nested inside two arr's. Here's what it looks like:
[
{
"views": "1,001,023",
"likes": "110,985",
"channel": "Red Cow",
"image": "https://i.imgur.com/l2Xfgpl.jpg",
"comments": [
{
"name": "Micheal Lyons",
"comment": "They BLEW the ROOF off at their last event, once everyone started figuring out they were going. This is still simply the greatest opening of an event I have EVER witnessed.",
"likes": 0,
},
{
"name": "Gary Wong",
"comment": "Every time I see him shred I feel so motivated to get off my couch and hop on my board. He’s so talented! I wish I can ride like him one day so I can really enjoy myself!",
"likes": 0,
},
{
"name": "Theodore Duncan",
"comment": "How can someone be so good!!! You can tell he lives for this and loves to do it every day. Every time I see him I feel instantly happy! He’s definitely my favorite ever!",
"likes": 0,
}
]
},
I've been trying to use .map to loop through it to pull the data of "name, comment and likes", so that it will be displayed on the website. Meaning, I have to go down two levels. First I loop through the initial arr > then access the comments arr > then loop through each index of the object. But with a loop I can only go down one level instead of two. Here's what I had attempted as well... looping through the first arr and then reassigning that value to another loop but I keep getting the message that firstLevel.map is undefined inside the return.
import VideoDetails from "../../data/video-details.json";
import Comment from "../Comment/Comment";
function CommentList() {
const firstLevel = VideoDetails.forEach((i) => {
return i.comments;
});
return (
<>
{firstLevel.map((event) => {
return (
<Comment
image={event.comments}
name={event.name}
timestamp={event.timestamp}
/>
);
})}
</>
);
}
export default CommentList;
The loop should output the following:
name: Michael Lyons, comment: They Below the ROOF off at their last event..., like: 0
name: Gary Wong, comment: Every time I see him..., likes: 0
and so on for each of the objects.
CodePudding user response:
It is not clear how you want the outer loop to work. Is that each Channel, I guess? But the function might look like this:
function CommentList() {
return VideoDetails.map((i) => {
return i.comments.map((event) => {
return {
<Comment
image={event.comments}
name={event.name}
timestamp={event.timestamp}
/>
}
})
})
}
CodePudding user response:
forEach don't return anything. you should use map
CodePudding user response:
You have to map over again as below:
const {useState} = React;
const VideoDetails = [
{
"views": "1,001,023",
"likes": "110,985",
"channel": "Red Cow",
"image": "https://i.imgur.com/l2Xfgpl.jpg",
"comments": [
{
"name": "Micheal Lyons",
"comment": "They BLEW the ROOF off at their last event, once everyone started figuring out they were going. This is still simply the greatest opening of an event I have EVER witnessed.",
"likes": 0,
},
{
"name": "Gary Wong",
"comment": "Every time I see him shred I feel so motivated to get off my couch and hop on my board. He’s so talented! I wish I can ride like him one day so I can really enjoy myself!",
"likes": 0,
},
{
"name": "Theodore Duncan",
"comment": "How can someone be so good!!! You can tell he lives for this and loves to do it every day. Every time I see him I feel instantly happy! He’s definitely my favorite ever!",
"likes": 0,
}
]
},
{
"views": "1,00771,023",
"likes": "11330,985",
"channel": "Milan Tv Show",
"image": "https://i.imgur.com/l2Xfgpl.jpg",
"comments": [
{
"name": "Micns",
"comment": "They BLEW the ROOF event, once everyone started figuring out they were going. This is still simplyning of an event I have EVER witnessed.",
"likes": 50,
},
{
"name": "Gang",
"comment": "Every tihred I feel so motivated to get off my couch and hop on my board. He’s so talented! Iay so I can really enjoy myself!",
"likes": 880,
},
{
"name": "Theoduncan",
"comment": "How can somed!!! You can tell he lives for this and loves to do it every day. Every time I see him I feel He’s definitely my favorite ever!",
"likes": 5880,
}
]
}
];
const App = () => {
return (
<div>
{VideoDetails.map(info=>{
return(
<div key={info.channel}>
<h2>{info.channel}</h2>
<br></br>
{info.comments.map(i=>(
<p key={i.name}><span>Name</span>: {i.name} -- <span>likes</span>: {i.likes} -- <span>Comment</span>: {i.comment}</p>
))}
<hr></hr>
</div>
)
})}
</div>
);
};
ReactDOM.createRoot(
document.getElementById("root")
).render(
<App/>
);
span{
color: crimson;
}
h2{
color: purple;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
CodePudding user response:
As mentioned the callback for forEach
doesn't return anything - you'll need to use map
.
It might be easier to visualise this as lots of components: Channels
, Channel
, Comments
, and Comment
, feeding only the relevant data to each one.
const { useState } = React;
// `map` over the main data and for each object
// in that array pass that data to a `Channel` component
function Channels({ data }) {
return (
data.map(obj => <Channel data={obj} />)
);
}
// Print the relevant channel information and
// pass down the comments array to the `Comments` component
function Channel({ data }) {
return (
<section className="channel">
<div className="channelInfo">
{data.channel}: {data.likes} likes
</div>
<CommentList comments={data.comments} />
</section>
);
}
// `map` over the comments array passing down
// each comment object to the `Comment` component
function CommentList({ comments }) {
return (
<section>
{comments.map(obj => {
return (
<Comment
comment={obj.comment}
name={obj.name}
likes={obj.likes}
/>
);
})}
</section>
);
}
// Display each comment using the comment object
function Comment({ comment, name, likes }) {
return (
<section className="sectionContainer">
<div className="comment">{comment}</div>
<div className="user">
<span className="name">{name}</span>:
<span className="likes">{likes} likes</span>
</div>
</section>
);
}
const data=[{views:"1,001,023",likes:"110,985",channel:"Red Cow",image:"https://i.imgur.com/l2Xfgpl.jpg",comments:[{name:"Micheal Lyons",comment:"They BLEW the ROOF off at their last event, once everyone started figuring out they were going. This is still simply the greatest opening of an event I have EVER witnessed.",likes:0},{name:"Gary Wong",comment:"Every time I see him shred I feel so motivated to get off my couch and hop on my board. He’s so talented! I wish I can ride like him one day so I can really enjoy myself!",likes:0},{name:"Theodore Duncan",comment:"How can someone be so good!!! You can tell he lives for this and loves to do it every day. Every time I see him I feel instantly happy! He’s definitely my favorite ever!",likes:0}]}];
ReactDOM.render(
<Channels data={data} />,
document.getElementById('react')
);
.channel { margin: 0.5em; }
.channelInfo { font-size: 1.4em; color: darkred; }
.sectionContainer:not(:last-child) { margin-bottom: 1em; }
.name { font-weight: 600; }
.user { margin-left: 0.5em; }
.comment { padding: 0.5em; margin: 0.5em; background-color: lightgray; }
.likes { color: orange; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>