Reputation: 297
component is getting data in the format given as below
demo.json
{
"id": "1",
"name": "john",
"addr": [
{
"addr1": "xyz",
"addr2": "abc",
"addr3": "st"
},
{
"addr1": "xyz",
"addr2": "abc",
"addr3": "st"
}
]
}
when I try to render the data, I get error TypeError: Cannot read property 'map' of undefined
render() {
console.log(this.state.itemDetail.addr); // able to see log as [{...},{...}]
return (
<div>
<h1> detail</h1>
<div>
<p>{this.state.itemDetail.name}</p> // able to display this
<div>
// getting error "TypeError: Cannot read property 'map' of undefined"
{this.state.itemDetail.addr.map(item => {
return <p>{item.addr1}</p>;
})}
</div>
// error: TypeError: Cannot read property '0' of undefined
<p>this.state.itemDetail.addr[0].addr1</P>;
</div>
</div>
);
}
when data is available inside render(), why internal data array of objects have issue? how to display this?
EDIT:
Providing below, ItemDetail code. after impl modifications suggested, execution doesn't throw errors but doesn't display addr or addr1.
data is fetched from local json-server using local demo.json.
ItemDetail.js
import React, { Component } from "react";
export default class ItemDetail extends Component {
constructor(props) {
super(props);
this.state = {
ItemDetail: {}
};
}
fetchItemDetail() {
fetch(` http://localhost:4000/items/${this.props.match.params.id}`)
.then(res => res.json())
.then(res => {
this.setState({
ItemDetail: res
});
})
.catch(console.log);
}
componentDidMount() {
this.fetchItemDetail();
}
render() {
return (
<div>
<h1>Item detail</h1>
<div>
<p>{this.state.ItemDetail.name}</p>
<p>{this.state.ItemDetail.destination}</p>
{Array.isArray(this.state.ItemDetail) &&
this.state.ItemDetail.addr.map(item => {
return <p>{item.description}</p>;
})}
<p>
{Array.isArray(this.state.itemDetail) &&
this.state.ItemDetail.addr.length &&
this.state.ItemDetail.addr[0].description}
</p>
</div>
</div>
);
}
}
Upvotes: 0
Views: 63
Reputation: 8308
Put in a check for this.state.itemDetail
to be not equal to undefined and then run the map. It's possible that it's undefined for first render and not for subsequent. I think the following should solve the problem.
{this.state.itemDetail && this.state.itemDetail.addr.length!==0 && this.state.itemDetail.addr.map(item => {
return <p>{item.addr1}</p>;
})}
Upvotes: 1
Reputation: 16122
Don't assume that you'll always get the right data, one of the most important things in programming is validating you data before you use it. Check if the value exists before using it. use Array.isArray to check if the value is array.
render() {
console.log(this.state.itemDetail.addr); // able to see log as [{...},{...}]
return (
<div>
<h1> detail</h1>
<div>
<p>{this.state.itemDetail.name}</p> // able to display this
<div>
// getting error "TypeError: Cannot read property 'map' of undefined"
{Array.isArray(this.state.itemDetail.addr) && this.state.itemDetail.addr.map(item => {
return <p>{item.addr1}</p>;
})}
</div>
// error: TypeError: Cannot read property '0' of undefined
<p>{Array.isArray(this.state.itemDetail.addr) && this.state.itemDetail.addr.length && this.state.itemDetail.addr[0].addr1}</P>;
</div>
</div>
);
}
Upvotes: 0