Reputation: 927
I've currently got a little react redux application where I am adding movies, and adding images as a nested array within my object.
What my state looks like after adding an item
{
movies: [
0:{
"title": "asda",
"director": "asda",
"genre": "asd",
"description": "asd",
"images": [
{
"name": "george-michael-306600-2-raw.jpg",
"type": "image/jpeg",
"size": "65 kB",
"base64": "data:image/jpeg;base64,/9j/IMAGE//Z",
"file": {}
}
],
"id": "ae04f1e8-18bb-434b-a3e3-b02d44e68d2a"
}
}
Then I render it in my component as follows
import React from 'react'
import Slider from 'react-slick'
import { dispatch, connect } from 'react-redux'
import {Icon} from 'react-fa'
import { deleteMovie } from '../../actions/movieActions'
import 'slick-carousel/slick/slick.css'
import 'slick-carousel/slick/slick-theme.css'
import './MovieList.scss'
class MovieList extends React.Component{
constructor(props){
super (props)
}
handleClick(id) {
dispatch(deleteMovie(id))
}
render () {
// Settings for slick-carousel
let settings = {
infinite: true,
speed: 500
}
return (
<div className='col-lg-12'>
{this.props.movies.map((b, i) =>
<div key={i} className="col-lg-2">
<Slider {...settings}>
{b.images.map((b, z) =>
<div className="img-wrapper">
<Icon name="trash" className="trash-icon" onClick={(e) =>
console.log(this.props.movies[i].id),
this.props.onMovieClick.bind(this.props.movies[i].id)
}/>
<img className="img-responsive" key={z} src={b.base64}></img>
</div>
)}
</Slider>
<div className="text-left info">
<h2>{b.title}</h2>
<p>{b.genre}</p>
</div>
</div>
)}
</div>
)
}
}
// map state from store to props
const mapStateToProps = (state) => {
return {
movies: state.movies
}
};
// Map actions to props
const mapDispatchToProps = (dispatch) => {
return {
onMovieClick: (id) => {
dispatch(deleteMovie(id))
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(MovieList)
Now this works perfectly find and my items render as intended until, I try to filter(delete) an item, then my inner loop to make the images into the slider {b.images.map((b, z)
fails and i get an error
Cannot read property 'map' of undefined
How can I protect this inner loop from attempting to render items, if array is empty/undefined?
In regular JS I'd simply wrap my map call in a check to see if images is undefined, but how does one address this issue in a JSX render block?
Thanks for your help
Upvotes: 0
Views: 88
Reputation: 3925
To protect against it you can use an existence check before doing the map like this:
{b.images && b.images.map((b, z) =>
<div className="img-wrapper">
<Icon name="trash" className="trash-icon" onClick={(e) =>
console.log(this.props.movies[i].id),
this.props.onMovieClick.bind(this.props.movies[i].id)
}/>
<img className="img-responsive" key={z} src={b.base64}></img>
</div>
)}
b.images
will check if b.images
is defined and then do the map. Otherwise it will render nothing.
Upvotes: 2