0
votes

I've made a GET request to the News API and received data as an object. Since the map method can only work on an array, I then use map on data.articles as it's an array. (checked in the console log on Line 22).

With that said, I don't understand why I'm still receiving

TypeError Cannot read property 'map' of undefined

https://codesandbox.io/s/elated-star-j9s8g?file=/src/App.js

function App() {
  const [apiUrl] = useState("https://gnews.io/api/v3/search?");
  const [apiKey] = useState("123456789");
  const [data, setData] = useState([]);
  const [query, setQuery] = useState("");
  const [url, setUrl] = useState(
    `https://gnews.io/api/v3/top-news?token=95e7679f627d5796aa24f6692def5df3`
  );

  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(url);
      setData(result.data);
    };
    fetchData();
  }, [url]);

  const searchHandler = () => {
    setUrl(`${apiUrl}q=${query}&token=${apiKey}`);
    console.log(data.articles);
  };

  let newsNodes = data.articles.map((item) => {
    return (
      <li key={item.publishedAt}>
        <a href={item.url}>{item.title}</a>
      </li>
    );
  });

  return (
    <>
      <input
        type="text"
        value={query}
        onChange={(event) => setQuery(event.target.value)}
      />
      <button type="button" onClick={searchHandler}>
        Search
      </button>
      <ul>{newsNodes}</ul>
    </>
  );
}
2
This should help you - stackoverflow.com/a/49477641/4160532. Your initial value to useState is set to [].Kedarnag Mukanahallipatna
The API hasn't returned by the time you're calling map, it's a race condition. Either set it to an empty array initially, or wait for data before calling map.Detail
@KedarnagMukanahallipatna Thanks for the linkln09nv2
@Detail Thanks for the cluesln09nv2

2 Answers

1
votes

As stated by the others, when the component is initally rendered, data.articles is undefined. This is evident if you log the data before map

enter image description here

You could probably have a condition that checks to see if it is not undefined, only then will you proceed with map

let newsNodes = data.articles && data.articles.map((item) => {
  return (
    <li key={item.publishedAt}>
      <a href={item.url}>{item.title}</a>
    </li>
  );
});
1
votes

In the initial value passed to useState, you initialize data to [], and [].articles is undefined.