Search code examples
javascriptreactjsreact-nativeasynchronoussynchronous

React JS Axios Response is not populating the array of objects returned by api. There are 20 objects returned by the response


enter image description herehope you are doing well. Im just using ReactJS and I utilized the axios request to get news from a third party API. Now, the API returned 20 different articles. So I tried to use the map function to map over and iterate over the 20 articles and to create 20 cards(I created a card component that the api info would populate into). There are 20 articles, which means that there should be 20 cards. However, only 1 card shows. Please see below for my code. Thanks!

[![// TrumpNews
import React, { useEffect, useState } from "react";
import "./TrumpNews.css";
import CardComponent from "./CardComponent";
import axios from "axios";

const TrumpNews = () => {
  const API_KEY = "0949535b152f400aa2a162ecc055021a";
  const \[news, setNews\] = useState(\[\]);

  console.log(news);

  useEffect(() => {
    var url =
      "http://newsapi.org/v2/everything?" +
      "q=Trump&" +
      "from=2020-11-12&" +
      "sortBy=popularity&" +
      "apiKey=*********";

    axios
      .get(url)
      .then(async (res) => {
        setNews(\[res.data.articles\]);
      })
      .catch((err) => console.log(err));
  }, \[\]);

  return (
    <div className="trumpNews">
      {news.map((item) => (
        <CardComponent item={item} />
      ))}
    </div>
  );
};

export default TrumpNews;


// CardComponent
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Card from "@material-ui/core/Card";
import CardHeader from "@material-ui/core/CardHeader";

import IconButton from "@material-ui/core/IconButton";
import Typography from "@material-ui/core/Typography";
import { red } from "@material-ui/core/colors";
import FavoriteIcon from "@material-ui/icons/Favorite";
import ShareIcon from "@material-ui/icons/Share";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import MoreVertIcon from "@material-ui/icons/MoreVert";
import "./CardComponent.css";

const useStyles = makeStyles((theme) => ({
  root: {
    maxWidth: 345,
  },
  media: {
    height: 0,
    paddingTop: "56.25%", // 16:9
  },
  expand: {
    transform: "rotate(0deg)",
    marginLeft: "auto",
    transition: theme.transitions.create("transform", {
      duration: theme.transitions.duration.shortest,
    }),
  },
  expandOpen: {
    transform: "rotate(180deg)",
  },
  avatar: {
    backgroundColor: red\[500\],
  },
}));

const CardComponent = ({ item }) => {
  const classes = useStyles();

  console.log(item.author);

  return (
    <Card className={classes.root}>
      <CardHeader
        action={
          <IconButton aria-label="settings">
            <MoreVertIcon />
          </IconButton>
        }
        title={item.description}
        subheader="September 14, 2016"
      />
      <br />
      <br />
      <br />
      <br />
      <br />
      <br />
      <br />
      <br />
      <br />
      <br />
      <div>{item\[0\].author}</div>
      {item\[0\].title}
    </Card>
  );
};

export default CardComponent;][1]][1]

Solution

  • You're creating a two dimensional array when you set the result -

    setNews([res.data.articles]);
    

    articles is already an array, so you just need to set the state like this -

    setNews(res.data.articles);