My code image is not displaying correctly. When I console axios calls are working fine.
import { Container, Grid, Paper } from '@mui/material';
import { useEffect, useState } from 'react';
import { styled } from '@mui/material/styles';
import ButtonBase from '@mui/material/ButtonBase';
import axios from 'axios';
const Img = styled('img')({
margin: 'auto',
display: 'block',
maxWidth: '100%',
maxHeight: '100%',
});
const Home = () => {
const [albums, setAlbums] = useState([]);
useEffect(async () => {
const res = await axios.get(`https://jsonplaceholder.typicode.com/albums?userId=2`);
let tempArr = JSON.parse(JSON.stringify(res)).data;
let photos = [];
tempArr.forEach(async (element, index) => {
let res2 = await axios.get(`https://jsonplaceholder.typicode.com/albums/${element.id}/photos`);
photos = JSON.parse(JSON.stringify(res2)).data;
element.photos = photos;
tempArr[index] = element;
});
setAlbums(tempArr);
}, []);
return (
<div>
<Container sx={{ marginTop: '10px;' }}>
<Grid container spacing={2}>
{albums.map((item, key) => {
return (
<Grid key={key} item sm={6} xs={12}>
<Paper sm={{ textAlign: 'center' }} sx={{ p: 2, margin: 'auto', flexGrow: 1 }}>
<Grid container spacing={2}>
<Grid item>
{(undefined !== item['photos'] && item['photos'].length) &&
<ButtonBase sx={{ width: 128, height: 128 }}>
<Img alt="complex" src={item['photos'][0]['thumbnailUrl']} />
</ButtonBase>
}
</Grid>
</Grid>
</Paper>
</Grid>
)
})}
</Grid>
</Container>
</div>
)
}
export default Home;
It would be a great help if someone can look into it. When I console.log just after setAlbums(tempArr); array looks like this,
[
{
"userId": 2,
"id": 11,
"title": "quam nostrum impedit mollitia quod et dolor",
"photos": [
{
"albumId": 11,
"id": 501,
"title": "asperiores exercitationem voluptates qui amet quae necessitatibus facere",
"url": "https://via.placeholder.com/600/cda4c0",
"thumbnailUrl": "https://via.placeholder.com/150/cda4c0"
},
{
"albumId": 11,
"id": 502,
"title": "omnis qui sit et",
"url": "https://via.placeholder.com/600/74e371",
"thumbnailUrl": "https://via.placeholder.com/150/74e371"
},
{
"albumId": 11,
"id": 503,
"title": "modi voluptas fugiat eos",
"url": "https://via.placeholder.com/600/9022fb",
"thumbnailUrl": "https://via.placeholder.com/150/9022fb"
},
]
}
]
And when I try <p>{item['photos'][0]['thumbnailUrl']}</p>
loop I'm getting error,
TypeError: Cannot read properties of undefined (reading '0')
CodePudding user response:
Based on this answer and this issue you could try to change the useEffect
to be like this:
useEffect( () => {
const fetchAlbums =async () => {
const res = await axios.get(`https://jsonplaceholder.typicode.com/albums?userId=2`);
const tempArr = JSON.parse(JSON.stringify(res)).data;
const tempAlbums = await Promise.all(tempArr.map(async (element) => {
const res2 = await axios.get(`https://jsonplaceholder.typicode.com/albums/${element.id}/photos`);
const photos = JSON.parse(JSON.stringify(res2)).data;
return { ...element, photos };
}));
setAlbums(tempAlbums);
}
fetchAlbums();
}, []);
And you can change the Img
like this to prevent the error you are seeing when there aren't photos:
<Img alt="complex" src={item.photos?.[0].thumbnailUrl || "<path to placeholder when the album has no photos>"} />