0

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>
    </>
  );
}
4
  • This should help you - stackoverflow.com/a/49477641/4160532. Your initial value to useState is set to []. Commented Sep 7, 2020 at 23:07
  • 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. Commented Sep 7, 2020 at 23:08
  • @KedarnagMukanahallipatna Thanks for the link Commented Sep 7, 2020 at 23:44
  • @Detail Thanks for the clues Commented Sep 7, 2020 at 23:45

2 Answers 2

1

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>
  );
});
Sign up to request clarification or add additional context in comments.

1 Comment

Putting this in my notes for future reference. Appreciate it!
1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.