TypeError: Cannot read properties of undefined (reading 'city')
I'm trying to loop through address keys and values but failed then I tried to access one value at a time and I got that error. I'm new to React and JS. When I try to log that value, I get the answer with no problem but as soon as I want to print it out one the screen, the error pops up. I have tried possible way I could think of and find online, but sadly nothing worked.
//this is a component that is supposed to show details of each hero
const HeroPage = () => {
const { id } = useParams();
const [hero, setHero] = useState({});
useEffect(() => {
const fetchHero = async () => {
const res = await fetch(
`https://jsonplaceholder.typicode.com/users/${id}`);
const data = await res.json();
setHero(data);
};
fetchHero();
}, [id]);
const address = hero.address;
return (
<div className="card-container-page box">
<div className="box-middle">
<h1>{hero.name}</h1>
<h3>{hero.email}</h3>
<h3>{hero.phone}</h3>
<h3>{address.city}</h3>
// I have also tried the following code
{Object.keys(hero).map((keyName, i) => (
<li className="card-container" key={i}>
<span className="input-label">
key: {i} Name: {hero[keyName]}
</span>
</li>
))}
</div>
</div>
);
};
export default HeroPage;
//JSON response I get
[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "[email protected]",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
}]
//https://jsonplaceholder.typicode.com/users
CodePudding user response:
It looks like your JSON response is an Array of objects.
This code will set that JSON response to the Hero state variable.
const fetchHero = async () => {
const res = await fetch(
`https://jsonplaceholder.typicode.com/users/${id}`
);
const data = await res.json();
setHero(data);
The type of hero is now an Array. So this line will be undefined:
const address = hero.address;
Instead, try accessing the first element of the array, like this:
const address = hero[0].address;
If we were to refactor this into a working component, you would write something like this.
const HeroPage = (props) => {
const [hero, setHero] = useState();
useEffect(() => {
const fetchHero = async () => {
const res = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
const data = await res.json();
setHero(data);
};
fetchHero();
}, [id]);
if (hero === undefined) {
return null;
}
return (
<div key={hero.id} className="card-container-page box">
<div className="box-middle">
<h1>{hero.name}</h1>
<h3>{hero.email}</h3>
<h3>{hero.phone}</h3>
<h3>{hero.address.city}</h3>
</div>
</div>
);
};
export default HeroPage;
Edit: re-working the example with the assumption that hero is an object.
Notice the check to see if hero === undefined. This is necessary because when state is initialized its value is undefined, before fetchHero gets a response and saves it in the state variable.