Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Image not loading when mapping Material-UI cards

I am kind of new to react, and this is the first time trying to take information from an API call, mapping through it, and making a Material-UI card for each response. When I make a single card, it comes out fine. When I map through the response, cards are made for each response, and text is entered into the fields correctly, but the image doesn't load. Even when using a static image not loaded from the response, the image doesn't show. Here is what I'm looking at:

//calls API, maps results, and builds cards

import React, {Component} from 'react'


import Request from 'superagent'
import Grid from '@material-ui/core/Grid'
import Cards from './cards'


const url = "http://localhost:4000/products"
const get = Request.get(url)

class ProductList extends Component {
    state = {
        products: []

    }

    constructor() {
        super()
        this.getProducts()
    }

    getProducts = () =>

    Request.get(url)
    .then((response) => {
        const prods = (response.body.products)
        console.log(prods)
        this.setState({products: prods})
    })

render() {
    return (
    <div>
        {this.state.products ? (

            <Grid container spacing={24} style = {{padding: 24}}>
            { this.state.products.map(prods => (
                <Grid item xs={8} sm={4} lg={4} xl={3}>
                 <Cards id={prods.id} name = {prods.name} quantity = {prods.quantity} price = {prods.price} image = {prods.iamge} />
                </Grid>

                ))}
            </Grid>
            ) : "No products found" }
    </div>
        )   
}

}


export default ProductList;

//builds cards

import React from 'react'


import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Card from '@material-ui/core/Card';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import Request from 'superagent';


const styles = {
  card: {
    maxWidth: 345,
  },
  media: {
    height: 0,
    paddingTop: '56.25%', // 16:9
  },
};

const Cards = (props) => {
    return(

        <div>
      <Card>
        <CardMedia
          image= {require ("./images/matcha.jpg")}
          title="{props.name}"
        />
        <CardContent>
          <Typography gutterBottom variant="headline" component="h2">
            {props.name}
          </Typography>
          <Typography component="p">
           {props.price}
          </Typography>
        </CardContent>
        <CardActions>
          <Button size="small" color="primary">
            Share
          </Button>
          <Button size="small" color="primary">
            Learn More
          </Button>
        </CardActions>
      </Card>
    </div>
  );


Cards.propTypes = {
  classes: PropTypes.object.isRequired,
}


}

export default Cards

//builds an individual card

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Card from '@material-ui/core/Card';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import Request from 'superagent';

const styles = {
  card: {
    maxWidth: 345,
  },
  media: {
    height: 0,
    paddingTop: '56.25%', // 16:9
  },
};

function SimpleMediaCard(props) {
  const url = "http://localhost:4000/products";
  const { classes } = props;
  return (
    <div>
      <Card className={classes.card}>
        <CardMedia
          className={classes.media}
          image= {require ("./images/matcha.jpg")}
          title="Contemplative Reptile"
        />
        <CardContent>
          <Typography gutterBottom variant="headline" component="h2">
            Lizard
          </Typography>
          <Typography component="p">
            Lizards are a widespread group of squamate reptiles, with over 6,000 species, ranging
            across all continents except Antarctica
          </Typography>
        </CardContent>
        <CardActions>
          <Button size="small" color="primary">
            Share
          </Button>
          <Button size="small" color="primary">
            Learn More
          </Button>
        </CardActions>
      </Card>
    </div>
  );
}

SimpleMediaCard.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(SimpleMediaCard);

//renders page

import React from 'react'

import PropTypes from 'prop-types'
import { withStyles } from '@material-ui/core/styles'
import Card from '@material-ui/core/Card'
import CardActions from '@material-ui/core/CardActions'
import CardContent from '@material-ui/core/CardContent'
import CardMedia from '@material-ui/core/CardMedia'
import Button from '@material-ui/core/Button'
import Typography from '@material-ui/core/Typography'
import MenuBar from '../menubar'
import SimpleMediaCard from '../card'
import ProductList from '../productList'




function Products (props) {
    return (
        <div>
        <MenuBar />
        <SimpleMediaCard />
        <ProductList />
        </div>

        )
}

export default Products

On the rendered page there are four cards. The first one is as it should be, picture and text included. The next three cards (there are three items in the database) show text but no images. I thought at first I was having an issue with webpack and the need for 'require', but even when using the static image link, still no image. Any ideas?

like image 658
WyoMonkey Avatar asked Jul 26 '18 15:07

WyoMonkey


3 Answers

After a day and a half of searching, the initial fix is pretty simple. CardMedia requires a height property in order to render an image. Adding

    <CardMedia style = {{ height: 0, paddingTop: '56%'}}
     image= {require ("./images/matcha.jpg")

at least rendered the static images. Hope this helps someone!

like image 164
WyoMonkey Avatar answered Oct 19 '22 19:10

WyoMonkey


Since CardMedia is a generic component for rendering different types of media, providing the source src alone isn't enough. The component prop should be used to tell CardMedia what to render

import image from '../path/to/images/imageName.jpg'
...
...
<CardMedia component="img" src={image}
like image 25
Luqman Avatar answered Oct 19 '22 18:10

Luqman


This work for me

import img from "./img/placeholder2.jpg";


 <CardMedia
          className={classes.media}
          image= {img}
          title="plcae holder"
        />
like image 41
Praveen Aanand Avatar answered Oct 19 '22 20:10

Praveen Aanand