I'm trying to get a Tv show to display on multiple cards. I'm just using one Tv show before I start adding any more. So it should basically display one tv show on all the cards.
The error is coming from the tvList.js.
tvList.js
import React from "react";
import Tv from "../tvCard/";
import Grid from "@material-ui/core/Grid";
const TvList = (props) => {
let tvCards = props.tvshows.map((m) => (
<Grid key={m.id} item xs={12} sm={6} md={4} lg={3} xl={2}>
<Tv key={m.id} tv={m} />
</Grid>
));
return tvCards;
};
export default TvList;
The Tv card seems to be fine and is working in my storybook.
tvCard.js
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Card from "@material-ui/core/Card";
import CardActions from "@material-ui/core/CardActions";
import CardContent from "@material-ui/core/CardContent";
import CardMedia from "@material-ui/core/CardMedia";
import CardHeader from "@material-ui/core/CardHeader";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";
import FavoriteIcon from "@material-ui/icons/Favorite";
import CalendarIcon from "@material-ui/icons/CalendarTodayTwoTone";
import StarRateIcon from "@material-ui/icons/StarRate";
import IconButton from "@material-ui/core/IconButton";
import Grid from "@material-ui/core/Grid";
import img from '../../images/tv-poster-placeholder.png'
const useStyles = makeStyles({
card: { maxWidth: 345 },
media: { height: 500 },
avatar: {
backgroundColor: "rgb(255, 0, 0)",
},
});
export default function TvCard(props) {
const classes = useStyles();
const tv = props.tv;
return (
<Card className={classes.card}>
<CardHeader className={classes.header} title={tv.name} />
<CardMedia
className={classes.media}
image={
tv.poster_path
? `https://image.tmdb.org/t/p/w500/${tv.poster_path}`
: img
}
/>
<CardContent>
<Grid container>
<Grid item xs={6}>
<Typography variant="h6" component="p">
<CalendarIcon fontSize="small" />
{tv.first_air_date}
</Typography>
</Grid>
<Grid item xs={6}>
<Typography variant="h6" component="p">
<StarRateIcon fontSize="small" />
{" "} {tv.vote_average}{" "}
</Typography>
</Grid>
</Grid>
</CardContent>
<CardActions disableSpacing>
<IconButton aria-label="add to favorites" onClick={null}>
<FavoriteIcon color="primary" fontSize="large" />
</IconButton>
<Button variant="outlined" size="medium" color="primary">
More Info ...
</Button>
</CardActions>
</Card>
);
}
tvPage.js
import React from "react";
import Header from "../components/headerTvList";
import FilterCard from "../components/filterTvCard";
import Grid from "@material-ui/core/Grid";
import { makeStyles } from "@material-ui/core/styles";
import TvList from "../components/tvList";
const useStyles = makeStyles({
root: {
padding: "20px",
},
});
const TvListPage = (props) => {
const classes = useStyles();
const tvshows = props.tvshows;
return (
<Grid container className={classes.root}>
<Grid item xs={12}>
<Header title={"Discover Tv Shows"} />
</Grid>
<Grid item container spacing={5}>
<Grid key="find" item xs={12} sm={6} md={4} lg={3} xl={2}>
<FilterCard />
</Grid>
<TvList tvshows={tvshows}></TvList>
</Grid>
</Grid>
);
};
export default TvListPage;
src/index.js
import React from "react";
import ReactDOM from "react-dom";
import TvPage from "./pages/tvPage";
const sample = {
"backdrop_path": "/wAEWZm2pSopAbqE5dQWE0ET8aR5.jpg",
"first_air_date": "2021-01-08",
"genre_ids": [
10759,
10765,
99
],
"id": 114695,
"name": "Marvel Studios: Legends",
"origin_country": [
"US"
],
"original_language": "en",
"original_name": "Marvel Studios: Legends",
"overview": "Revisit the epic heroes, villains and moments from across the MCU in preparation for the stories still to come. Each dynamic segment feeds directly into the upcoming series — setting the stage for future events. This series weaves together the many threads that constitute the unparalleled Marvel Cinematic Universe.",
"popularity": 140.788,
"poster_path": "/EpDuYIK81YtCUT3gH2JDpyj8Qk.jpg",
"vote_average": 7.6,
"vote_count": 515
}
const tvshows = [sample, sample, sample, sample, sample, sample, sample];
const App = () => {
return (
<TvPage tvshows={tvshows} />
);
};
ReactDOM.render(<App />, document.getElementById("root"));
CodePudding user response:
It could be an with the tvPage component.
const tvshows = props.tvshows;
Here the value of tvshows might be empty initially. I'd suggest i your TvList component do an null check.
const TvList = (props) => {
let tvCards = props.tvshows?.map((m) => (
<Grid key={m.id} item xs={12} sm={6} md={4} lg={3} xl={2}>
<Tv key={m.id} tv={m} />
</Grid>
));
return tvCards;
};
The ?
is an [optional chaining] operator(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining).
CodePudding user response:
The error is that for some reason, props.tvshows
is undefined within TvList
, even though it should be passed down from App
to TvPage
to TvList
. At some point down the line, tvshows
is lost.
I would suggest logging all instances of tvshows
, starting from when it is first defined in App
, then logging in TvPage
, then TvList
, to see where exactly the problem is coming from. Once you've found it, do some debugging to make the problem stop.