I got the error: TypeError: Cannot read property 'map' of undefined
when I am trying to build a const value to inject inside a Gallery. The const
is build using a JSON
Here is the class where the issue happened:
class ClassDetails extends React.Component {
constructor(props, context) {
super(props);
this.state = {anchorEl: null,
showJoin: false,
classDetailsInfo: ''};
}
componentDidMount = () => {
this.setState({classDetailsInfo: ClassDataUseCase.getClassDetails()})
}
render() {
const CLASS_PIC_LIST = this.state.classDetailsInfo.classpic
const GALLERY = CLASS_PIC_LIST.map((pic) => ({
src: pic,
thumbnail: pic, //.replace("1280","_480"), // for example
thumbnailWidth: 156,
thumbnailHeight: 156
}));
...
}
}
export default ClassDetails;
The exact error is TypeError: Cannot read property 'map' of undefined
and happened when doing const GALLERY = CLASS_PIC_LIST.map((pic) => ({
The classDetailsInfo
is set using ClassDataUseCase.getClassDetails()
defined as below:
class ClassDataUseCase {
static getAllClasses() {
return JSON.parse(ClassDetailsData.Classes)
}
static getClassDetails(id) {
var jsonClasses = JSON.parse(ClassDetailsData.Classes);
for(let k=0;k< jsonClasses.length;k++){
if(jsonClasses[k].id===id){
return jsonClasses[k];
}
}
}
}
and the data are coming from the ClassDetailsData
which is a JSON as defined below:
class ClassDetailsData {
static Classes = [{
"id": "c000001",
"title": "Cook like a chef",
"price": "5",
"teacher": "Arthur Patrick",
"teacherpic": "https://cdn.pixabay.com/photo/2015/03/03/08/55/portrait-657116_1280.jpg",
"teacherid": "u0000000001",
"desc": "Always want to learn to cook, that's the place you need to be",
"bring": "Your fun , your motivation and you",
"tags": [],
"address": {
"id":"",
"Name": "Joel Robuchon",
"address1": "3799 S Las vegas boulevard",
"address2": "",
"city": "las vegas",
"county": "Clark",
"zip": "89109",
"state": "Nevada",
"country": "United States"
},
"date": "2021/09/01",
"time": "1:00PM",
"duration": "2",
"classpic": ["https://cdn.pixabay.com/photo/2014/06/16/23/10/spice-370114_1280.jpg",
"https://cdn.pixabay.com/photo/2015/08/13/18/47/spices-887348_1280.jpg",
"https://cdn.pixabay.com/photo/2015/04/20/13/30/kitchen-731351_1280.jpg",
"https://cdn.pixabay.com/photo/2015/07/02/10/40/writing-828911_1280.jpg"],
"reviews": [{
"name": "Gabby Caldwell",
"profilePic":"https://cdn.pixabay.com/photo/2015/03/03/08/55/portrait-657116_960_720.jpg",
"rate": "5",
"total_review": "13",
"text": "Rachel was such a kind and knowledgeable guide. She took us to see some hidden coves that a lot of tourists probabaly miss. I’m keeping the map I made FOREVER!!!"
}],
},
{........}
];
}
export default ClassDetailsData;
I do not understand why it's complaining. any idea? thanks
In the constructor
you are declaring your state with classDetailsInfo
as a empty string, and a string doesn't have a .map
method on it.
this.state = {anchorEl: null,
showJoin: false,
classDetailsInfo: ''};
You need to declare the classDetailsInfo
as an appropriate type for it not to break on the initial render.
this.state = {anchorEl: null,
showJoin: false,
classDetailsInfo: {
classpic: []
}
};
In your state you define classDetailsInfo
as a string, that's the reason why you are getting that error
You should set initially it equal to an empty array []
to avoid unexpected behavior
class App extends React.Component { constructor(props) { super(props); this.state = { classList: '' } } componentDidMount() { this.setState({classList: ["name", "data", "test"]}); } render() { return <div> {this.state.classList.map(cl => <span>{cl}</span>)} </div> } } ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.1.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.1.1/umd/react-dom.production.min.js"></script> <div id="root"></div>
You can look this simple example, If I change the value of state key classList
to an []
every thing work as expected. But now It reproduces the same error you get
class App extends React.Component { constructor(props) { super(props); this.state = { classList: [] } } componentDidMount() { this.setState({classList: ["name", "data", "test"]}); } render() { return <div> {this.state.classList.map(cl => <span>{cl}</span>)} </div> } } ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="root"></div>
In the second example after I initialize classList to an array it work.
There might be case when this.state.classDetailsInfo.classpic
don't have the value. So initialize
it with a default []
if it does not have any value.
You can do it like this:
const CLASS_PIC_LIST = this.state.classDetailsInfo.classpic || [];
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.