Home > Mobile >  How to loop through an object that is nested inside two arrays? Using React
How to loop through an object that is nested inside two arrays? Using React

Time:09-29

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>:&nbsp;
        <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>

  • Related