Reputation: 105
I'm trying to use the map function to render images with Material UI, but I have to fetch the url from the API before displaying them, that is what getFoto() is doing, but It displays nothing
return(
<div className={classes.root}>
<GridList cellHeight={180} className={classes.gridList}>
<GridListTile key="Subheader" cols={2} style={{ height: 'auto' }}>
</GridListTile>
{data && data.map((tile) => (
<GridListTile key={tile.propertyId} >
<Link to={`/AreasRegistradas/${tile.propertyId}`}>
<img src={(async () => { // <======Here is the problem
await getFoto(tile.propertyId)
})()}
alt={tile.propertyName}
className={"MuiGridListTile-tile"}
/>
</Link>
<GridListTileBar
title={tile.propertyName}
subtitle={<span> {tile.address}</span>}
actionIcon={
<div>
<IconButton aria-label={`info about ${tile.title}`} className={classes.icon} onClick={()=>console.log("edit")}>
<EditIcon />
</IconButton>
<IconButton aria-label={`info about ${tile.title}`} className={classes.icon} onClick={()=>console.log("delete")}>
<DeleteForeverIcon />
</IconButton>
</div>
}
/>
</GridListTile>
))
}
</GridList>
</div>
)
However, if I do console.log (await getFoto(tile.propertyId)) it returns the correct urls that I need
//.....
<img src={(async () => {
console.log(await getFoto(tile.propertyId)) //this returns the values that I need in the console
})()}
//.....
What can be the problem here? I'm new in this async functions world please help. Thanks!
Im using:
-"react": "^16.13.1"
Upvotes: 0
Views: 4282
Reputation: 105
Thanks to see sharper for the advice!!! Here's what I did: First I created a new component called < Tile /> , added it inside my original map function and passed the item as props:
//...
{data && data.map((tile) => (
<div key={tile.propertyId}>
<Tile tile={tile} />
</div>
))
}
//...
Then inside my new < Tile /> component I added what I had originally inside my map function plus the async function inside a useEffect hook and store the fetched url in a useState hook:
function Tile(props){
const {tile} = props
const [imgSrc, setImgSrc] = useState(''); // here is the hook for the url
useEffect(() => {
const getFoto = async (propId) =>{
try{
const url = `....url/${propId}/images`
const response = await fetch(url, {
//authorization stuff
}
});
const responseData = await response.json()
setImgSrc(responseData.items[0].imageUrl) //setting the fetched url in a hook
}catch(error){
console.log(error)
}
}
getFoto(tile.propertyId);
}, []);
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-around',
overflow: 'hidden',
backgroundColor: theme.palette.background.paper,
},
gridList: {
width: 500,
height: 450,
},
icon: {
color: 'rgba(255, 255, 255, 0.54)',
},
}));
const classes = useStyles();
return(
<GridListTile className={"MuiGridListTile-tile"}>
<Link to={`/AreasRegistradas/${tile.propertyId}`}>
<img src={imgSrc}
alt={tile.propertyName}
className={"MuiGridListTile-tile"}
/>
</Link>
<GridListTileBar
title={tile.propertyName}
subtitle={<span> {tile.address}</span>}
actionIcon={
<div>
<IconButton aria-label={`info about ${tile.title}`} className={classes.icon} onClick={()=>console.log("edit")}>
<EditIcon />
</IconButton>
<IconButton aria-label={`info about ${tile.title}`} className={classes.icon} onClick={()=>console.log("delete")}>
<DeleteForeverIcon />
</IconButton>
</div>
}
/>
</GridListTile>
)
}
Thanks again!
Upvotes: 0
Reputation: 12055
When you set src={await getFoto(...)}
you are setting the src
attribute (a string obviously) to a Promise, which clearly won't work. Rather, somewhere in your component code, such as the componentDidMount
event, you should fetch the image and set the result to some state variable which then becomes the src:
async componentDidMount() {
const photo = await getFoto(tile.propertyId);
this.setState({photo});
}
...
render() {
...
<img src={state.photo} />
But note, this is assuming that what is returned is photo URL. If it's the image itself, you'll need to use base64. Something like src={
data:image/png;base64,${state.photo}}
. It also assumes title
is in scope in the componentDidMount
method. If it isn't, you'll need to use the correct reference (e.g. this.tile
, this.props.tile
?).
Upvotes: 1