Reputation: 241
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?
Upvotes: 6
Views: 18104
Reputation: 139
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}
Upvotes: 12
Reputation: 1
If you are using Firebase Storage, do the following:
<CardMedia
className={classes.media}
component="img"
src={collection.docId.downloadUrl}
title="Whatever"
/>
Upvotes: 0
Reputation: 186
Adding this in case some one needed dynamic image loading with material UI Card component
note the use of require.context for import path and the template literals for image variable
const img = require.context('assets/img', true);
<CardMedia
className={classes.media}
image={img(`./${imgSrc}`)}
title='description goes..'
/>
Upvotes: 0
Reputation: 117
This work for me
import img from "./img/placeholder2.jpg";
<CardMedia
className={classes.media}
image= {img}
title="plcae holder"
/>
Upvotes: 5
Reputation: 241
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!
Upvotes: 18