Home > Enterprise >  Render data got from axios using maerial ui (image not displaying)
Render data got from axios using maerial ui (image not displaying)

Time:11-18

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>"} />
  • Related