for a few days now I'm trying to solve the following problem. Of course I have researched and tried several solutions to the error message and unfortunately none of them work. I do not know what I'm doing wrong and would therefore like to ask you about it. :)
Error-Message: "TypeError: Cannot read properties of undefined (reading 'map')"
Code:
function App() {
const [games, setGames] = useState();
useEffect(() => {
getGames();
async function getGames() {
const response = await fetch(
"https://v3.football.api-sports.io/fixtures?season=2021&league=78&date=2021-12-04",
{
method: "GET",
headers: {
"x-rapidapi-host": "v3.football.api-sports.io",
"x-apisports-key": "XXX",
},
}
);
const data = await response.json();
setGames(data.parameters);
}
}, []);
return (
<div>
<h1>Games</h1>
<div className="games">
{games.map((game, index) => (
<div key={index}>
<h2>{game.season}</h2>
</div>
))}
</div>
)
</div>
);
}
export default App;
JSON: JSON GET EXAMPLE Later I would like to extract the teams from the JSON file. For example: response.teams.home.name
Thank you in advance for your attention! :) If there is any information missing, please let me know.
Many greetings and thanks
CodePudding user response:
Can you try this?
function App() {
const [games, setGames] = useState({});
useEffect(() => {
getGames();
async function getGames() {
const response = await fetch(
"https://v3.football.api-sports.io/fixtures?season=2021&league=78&date=2021-12-04",
{
method: "GET",
headers: {
"x-rapidapi-host": "v3.football.api-sports.io",
"x-apisports-key": "3914b827d25c9a793d6af1ec9c312d55",
},
}
);
const data = await response.json();
setGames(data.parameters);
}
}, []);
return (
<div>
<h1>Games</h1>
<div className="games">
{Object.keys(games).length > 0 && games.map((game, index) => (
<div key={index}>
<h2>{game.season}</h2>
</div>
))}
</div>
)
</div>
);
}
export default App;
CodePudding user response:
You need to understand the structure of your data, if you want to map over it appropriately.
Note: Do not use an array index for the key
of an item in a mapping. Each game contains a fixture
object with an id
.
const API_KEY = prompt('Supply the API key'); // Provide the key first!
const { useEffect, useState } = React;
const apiHost = 'v3.football.api-sports.io';
const apiUrl = `https://${apiHost}/fixtures`;
const apiKey = API_KEY;
const toParamString = (obj) => new URLSearchParams(obj).toString();
const getGames = ({ season, league, date }) => {
const url = `${apiUrl}?${toParamString({ season, league, date })}`;
return fetch(url, {
method: 'GET',
headers: {
'x-rapidapi-host': 'v3.football.api-sports.io',
'x-apisports-key': apiKey,
},
})
.then(response => response.json())
.then(data => data.response);
};
const Score = (props) => {
const { game: { fixture: { date }, score: { fulltime }, teams } } = props;
return (
<div className="score">
<div className="score-date">{new Date(date).toLocaleString()}</div>
<div className="score-grid">
<div>{teams.home.name}</div>
<div>{teams.away.name}</div>
<div>{fulltime.home}</div>
<div>{fulltime.away}</div>
</div>
</div>
);
};
const App = () => {
const [games, setGames] = useState([]);
useEffect(() => {
getGames({
season: 2021,
league: 78,
date: '2021-12-04'
}).then(data => setGames(data));
}, []);
return (
<div>
<h1 style={{ textAlign: 'center' }}>Games</h1>
<div className="games">
{games.map((game) => {
const { fixture: { id } } = game;
return (
<Score key={id} game={game} />
);
})}
</div>
</div>
);
};
ReactDOM.render(<App />, document.getElementById('react-app'));
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
flex: 1;
}
#react-app {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
}
.score {
border: thin solid grey;
margin: 0.667em;
padding: 0.33em;
}
.score-date {
display: flex;
justify-content: center;
font-weight: bold;
font-size: larger;
margin-bottom: 0.25em;
}
.score-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
.score-grid div {
display: flex;
justify-content: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react-app"></div>