I'm trying to make a 'Favorite Albums' app using React, GraphQL, Apollo, MongoDB, and Express. I'm having trouble implementing a feature that automatically grabs cover art from a localhost server that queries the MusicBrainz API. So far, the art-fetching aspect works perfectly: if I enter an artist + album combination, I get the cover art and that album is returned to the client side.
My ideal flow is this:
thumbnail
property (a URL to the cover art),
The problem is, getAlbumCover(album)
always returns a promise, as async
functions seem to do. I'm just not sure what I have to do to make it return the URL from the fetch operation. Any help would be immensely appreciated.
Below is the code for the Album
component.
import { useState } from 'react';
const Album = (props) => {
const getAlbumCover = async (album) => {
// Slugify text:
function convertToSlug(Text) {
return Text
.toLowerCase()
.replace(/ /g, '-')
.replace(/\//g, '-')
.replace(/[^\w-]+/g, '')
;
}
const artist = convertToSlug(album.artist.name);
const name = convertToSlug(album.name);
var result = await fetch(`http://localhost:5000/album-art/${artist}/${name}`, {
method: 'get',
headers: {
'Accept': 'application/json'
}
})
.then(res => res.json())
.then((result) => {
return (<img id={`img-${album.id}`} src={result} />);
})
}
const album = props.album;
return (
<div className="album-container">
<img id={`img-${album.id}`} src={album.thumbnail ? album.thumbnail : getAlbumCover(album)} />
<div className="album-header">
<h3><em>{album.name}</em> <span className="details-yor">({album.yearOfRelease})</span></h3>
<h3>- {album.artist.name}</h3>
</div>
</div>
)
}
export default Album;
If the cover needs to be retrieved, put it into state:
const Album = (props) => {
const [cover, setCover] = useState('');
Get the cover, if needed, when the component mounts:
useEffect(() => {
if (!props.album.thumbnail) {
getAlbumCover();
}
}, []);
// inside getAlbumCover:
.then(res => res.json())
.then(setCover)
.catch(handleError); // don't forget this; unhandled rejections should always be avoided
Then render it:
<img id={`img-${album.id}`} src={album.thumbnail || cover} />