简体   繁体   中英

TypeError: Cannot read properties of undefined (reading 'map') when calling from an API

Im really stuck on a problem - if you run the code below you will get an error "TypeError: Cannot read properties of undefined (reading 'map') ".

When i console log out the "items" var I get 2 results as shown here: 在此处输入图片说明

The problem lies within the first result as it is empty. But can someone explain to me why this result is empty and why it produces 2 results?

This code was taken directly from here and modified to suit what is returned from the API. Please consider running this code so you can see what i mean.

import React, {useState, useEffect} from 'react';
import logo from './logo.svg';
import './App.css';

function App() {

  const [error, setError] = useState(null);
  const [isLoaded, setIsLoaded] = useState(false);
  const [items, setItems] = useState([]);

  useEffect(() => {
    fetch("http://www.7timer.info/bin/api.pl?lon=113.17&lat=23.09&product=astro&output=json")
  .then(res => res.json())
  .then(
    (result) => {
      setIsLoaded(true);
       setItems(result); 
    },
    // Note: it's important to handle errors here
    // instead of a catch() block so that we don't swallow
    // exceptions from actual bugs in components.
    (error) => {
      setIsLoaded(true);
      setError(error);
    }
  )
  }, [])


  if (error) {
    return <div>Error: {error.message}</div>;
  } else if (!isLoaded) {
    return <div>Loading...</div>;
  } else {
return (
  <ul>
    {items.dataseries.map(item => (
       {console.log(item)}
    ))}
</ul>
    );
  }
}

export default App;

There are two mistakes which I could see

  1. One being the data you're fetching is an object while you're setting it initially to be an array and you're also using map function which can only be used on arrays.
  2. Initially your array doesn't contain dataseries also you can't access property like that in an array right (because array have indexes by which we get the there value).

So what you could do is instead set this function to be like this

useEffect(() => {
fetch("http://www.7timer.info/bin/api.pllon=113.17&lat=23.09&product=astro&output=json")
.then(res => res.json())
.then(
  (result) => {
  setIsLoaded(true);
   setItems(result.dataseries); 
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
  (error) => {
    setIsLoaded(true);
    setError(error);
  }
)}, [])

And return function to be something like this

return (
  <ul>
    {items.map(item => (
      {console.log(item)}
    ))}
  </ul>
);

Items is an array not the object eg [{...}, {...}] , desiredseries is inside object, not items.

 <ul>
        {items.map(item => item.dataseries.map(ds=> (
           {console.log(ds)}
        )))}
    </ul>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM