Home > Back-end >  Looping through axios API returns undefined
Looping through axios API returns undefined

Time:10-06

I'm pulling an object out of an API that I'm using to show data on a website.

Here's the object:

{
  "id": "25ce5d91-a262-4dcf-bb87-42b87546bcfa",
  "title": "Les Houches The Hidden Gem Of The Chamonix",
  "channel": "Cornelia Blair",
  "image": "https://i.imgur.com/yFS8EBr.jpg",
  "description": "Les Houches, located 6 kilometres from Chamonix, is a ski resort with a domain which extends from an altitude of 950 metres up to 1900 metres. Long descents through tree-lined slopes are combined with impressive views of the Mont Blanc massif and the Chamonix valley. Les Houches is twinned with the Russian villages of Sochi and Krasnaya-Polyana and was chosen by the International Olympic Committee to assist in the organization of the 2014 Winter Olympic Games. Watch for more fun facts!",
  "views": "16,950",
  "likes": "3,856",
  "duration": "4:13",
  "video": "https://project-2-api.herokuapp.com/stream",
  "timestamp": 1622991672000,
  "comments": [
    {
      "id": "7ba106bf-e74a-4c21-b59e-c485a30eea45",
      "name": "Giovana Alpine",
      "comment": "Wow! You can bet that we’ll be checking this place out when we’re in the area. The views look absolutely breathtaking. Thank you so much for sharing this with the world!",
      "likes": 0,
      "timestamp": 1623104591000
    },
    {
      "id": "921f0e8d-f9d1-44db-b4a2-a2718339891e",
      "name": "Victoire Lesage",
      "comment": "Skiing is a lifestyle! This may be hard to believe now, but I once competed here for the World Cup. The Alps are at their most beautiful when you’re shredding down them FAST.",
      "likes": 0,
      "timestamp": 1623071160000
    },
    {
      "id": "f7b9027b-e407-45fa-98f3-7d8a308ddf7c",
      "name": "Sharon Tillson",
      "comment": "Amazing footage of an amazing spot! It’s so inspiring to watch the sun rising over a landscape like this. I can only imagine how fresh the air must feel there on a snowy morning.",
      "likes": 3,
      "timestamp": 1623002522000
    }
  ]
}

I'm then using this data and pass it down to others components, i.e. FeaturedVideo, FeaturedVideoDescription as it can be seen in the app.js, which is working just fine.

function VideoPage() {
    const [details, setDetails] = useState([]);

    const { videoId } = useParams();

    useEffect(() => {
        axios
            .get(
                `https://project-2-api.herokuapp.com/videos/${videoId}?api_key=removed for privacy`
            )
            .then((resp) => setDetails(resp.data));
    }, []);

    return (
        <>
            <FeaturedVideo selectedVideo={details} />
            <FeaturedVideoDescription selectedVideo={details} />
            <div className="information">
                <div>
                    <CommentList selectedVideo={details} />
                </div>
            </div>
        </>
    );
}

However, when I then pass it down to the component: CommentList component it stops working. It's giving me the following error "cannot read properties of undefined (reading 'map')". Meaning, there seems to be an issue inside the CommentList component where I'm mapping through the data.

function CommentList({ selectedVideo }) {
    return (
        <>
            <section className="comments">
                {selectedVideo.comments.map((comment) => {
                    return (
                        <Comment
                            name={comment.name}
                            timestamp={comment.timestamp}
                            comment={comment.comment}
                            key={uniqid()}
                        />
                    );
                })}
            </section>
        </>
    );
}

As it's undefined it means that it's not pulling the data from the API properly? But why is that?

I've also imported axios, useEffect and all the other things that are needed to run this code but decided to not include it in the code snippet here.

CodePudding user response:

{selectedVideo?.comments?.map((comment) => {

You got an error because before to get your data and call the setState function, it is actually undefined so you must wait until it is available and the question mark will help you.

You can also check is details is an empty array or not and decide to render your component or not like this:

if(details.length > 0) return <CommentList selectedVideo={details} />

CodePudding user response:

By the first render selectedVideo.comments is still undefined i.e., during initial render the Comment has comment prop with []

a small e.g.

const data = [];
console.log(data.some_prop.map(()=>{}))

so is the error ... you can use optional chaining one of few ways

  • Related