Reputation: 69
I'm trying to show list of films using redux and material ui.
FilmsService :
export const FilmServices = {
getAllFilms,
};
function getAllFilms(){
return axios.get(config.baseUrl).then((response)=>{
return response;
}).catch((err)=>{
console.log(err);
})
}
FilmAction :
export function getAllFilms() {
return dispatch => {
FilmServices.getAllFilms()
.then((response) => {
if (response) {
dispatch(GET_FILMS(response));
}
})
}
}
FilmReducer :
const initialState = { films: [] }
export function filmreducer(state = initialState, action) {
switch (action.type) {
case 'GET_FILMS':
console.log(action);
return{
...state,
films : action.payload.data
};
case 'GET_FILMS_BY_NAME':
return{
...state,
films : action.payload.data
};
default:
return state
}
}
And this is my component :
import React , { Component }from 'react';
import PropTypes from 'prop-types';
import {makeStyles, withStyles} from '@material-ui/core/styles';
import {getAllFilms} from "../store/actions/FilmActions";
import Button from '@material-ui/core/Button';
import Card from "@material-ui/core/Card/Card";
import CardActionArea from "@material-ui/core/CardActionArea/CardActionArea";
import CardMedia from "@material-ui/core/CardMedia/CardMedia";
import CardContent from "@material-ui/core/CardContent/CardContent";
import Typography from "@material-ui/core/Typography/Typography";
import CardActions from "@material-ui/core/CardActions/CardActions";
import connect from "react-redux/es/connect/connect";
import { withRouter } from 'react-router-dom';
const useStyles = makeStyles({
card: {
maxWidth: 345,
},
});
class FilmsCard extends Component {
componentDidMount () {
const {dispatch} = this.props;
dispatch(getAllFilms());
}
constructor(props) {
super(props);
this.state = {
change: ''
};
}
render() {
const films = this.props.films || [];
return (
<Card>
{films.map(film => {
return(
<CardActionArea>
<CardMedia
component="img"
alt="Contemplative Reptile"
height="140"
image="/static/images/cards/contemplative-reptile.jpg"
title="Contemplative Reptile"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
{film.show ? film.show.name : film.name}
</Typography>
<Typography variant="body2" color="textSecondary" component="p">
{film.show ? film.show.name : film.name}
</Typography>
</CardContent>
</CardActionArea>
)})}
<CardActions>
<Button size="small" color="primary">
Share
</Button>
<Button size="small" color="primary">
Learn More
</Button>
</CardActions>
</Card>
);
}
}
FilmsCard.propTypes = {
classes: PropTypes.object.isRequired,
};
const mapStateToProps = (state) => {
return {
films : state.filmreducer
};
}
const connectedVendorPage = withRouter(connect(mapStateToProps, null, null, {
pure: false
})(withStyles(useStyles)(FilmsCard)));
export { connectedVendorPage as FilmsCard };
when i run i got this error :
TypeError: Cannot read property 'length' of undefined
I have problem with material ui i think because when i try this code in a simple component (without material ui ) i don't get errors.
Can anyone help me please ? Thank you
Upvotes: 1
Views: 798
Reputation: 69
Also by changing this part of code worked for me :
const useStyles = makeStyles({
card: {
maxWidth: 345,
},
});
changed to this :
const styles = theme => ({
card: {
maxWidth: 345,
},
media: {
height: 50,
},
});
Upvotes: 1
Reputation: 69
@Muhammad Awais I have changer my render() like this and it worked :
render() {
const { classes } = this.props;
const { films } = this.props.films;
return (
<Card className={classes.card}>
{films.map(film => {
return(
<CardActionArea>
<CardMedia
className={classes.media}
component="img"
alt="Contemplative Reptile"
height="140"
image="http://static.tvmaze.com/uploads/images/medium_portrait/168/421041.jpg"
title="Contemplative Reptile"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
{film.show ? film.show.name : film.name}
</Typography>
<Typography variant="body2" color="textSecondary" component="p">
{film.show ? film.show.name : film.name}
</Typography>
</CardContent>
</CardActionArea>
)})}
<CardActions>
<Button size="small" color="primary">
Share
</Button>
<Button size="small" color="primary">
Learn More
</Button>
</CardActions>
</Card>
);
}
}
Upvotes: 1
Reputation: 38
In render() method, remove this line const { films } = this.props.films;
and try this:
const films = this.props.films || [];
and also, please remove console.log(this.props.films)
in constructor.
Update FilmAction with this:
export function getAllFilms() {
return dispatch => {
return FilmServices.getAllFilms()
.then((response) => {
if (response) {
dispatch(GET_FILMS(response));
}
})
}
}
Upvotes: 0