I have a React app where I am trying to display data fetched from my backend. My goal is to fetch my data (spotify playlists, tracks, and artists) onclick of one of the genres.
then group them all together with promise.all, and send them to the results component with usenavigate:
navigate(`/${genre}`, { state: { artists, playlists, tracks } });
Then in Results, send the relevant data to it’s component (playlists data to playlists component,
tracks data to tracks component, and artists data to artists componenet). but when I click one of the
artists, I still want to send the post request and be routed to /${artist.name}
and send all the
data that comes back with it to be displayed in the toptracks component.
I’m pretty positive the data IS being sent to the toptracks component. there is just something wrong
with the data that is getting passed to the artists, playlists, and tracks components.
it is somehow becoming undefined, and I’m not sure why.
These are my errors:
Cannot destructure property 'artists' of 'props.data.artists' as it is undefined.
Uncaught TypeError: Cannot read properties of undefined (reading 'playlists')
Uncaught TypeError: Cannot read properties of undefined (reading 'tracks')
here are the components:
Genres.js
import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
function Genres() {
const [genres, setGenres] = useState([]);
const navigate = useNavigate();
useEffect(() => {
fetch("/api/genres/")
.then((response) => response.json())
.then((data) => setGenres(data.genres))
.catch((error) => console.log(error));
}, []);
function handleClick(genre) {
const query_params = {
genre: genre
};
Promise.all([
fetch("/api/artists/", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(query_params),
}),
fetch("/api/playlists/", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(query_params),
}),
fetch("/api/tracks/", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(query_params),
})
])
.then((responses) => Promise.all(responses.map((response) => response.json())))
.then(([artists, playlists, tracks]) => {
console.log({ artists, playlists, tracks });
navigate(`/${genre}`, { state: { artists, playlists, tracks } });
})
.catch((error) => console.log(error));
}
return (
<div>
<div className="genre-list-container">
<ul className="genre-list">
{genres.map((genre) => (
<li
className="genre"
key={genre}
onClick={() => handleClick(genre)}
>
{genre}
</li>
))}
</ul>
</div>
</div>
);
}
export default Genres;
Results.js
import React from 'react'
import Artists from './Artists'
import Playlists from './Playlists'
import Tracks from './Tracks'
import { useLocation } from "react-router-dom";
function Results() {
const location = useLocation();
return (
<div>
<Artists data={location.state} />
<Playlists data={location.state} />
<Tracks data={location.state} />
</div>
);
}
export default Results;
Artists.js
import React, { useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
function Artists(props) {
const { artists } = props.data.artists;
const navigate = useNavigate();
function handleClick(artist) {
fetch("/api/top_tracks/", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ artist_id: artist.id }),
})
.then((response) => response.json())
.then((data) => {
console.log(data);
navigate(`/${artist.name}`, { state: { data } });
});
}
// console.log(artists.map((artist) => (artist.name)))
return (
<div>
<div>Artists:</div>
{artists.map((artist) => (
<div key={artist.id}>
<img src={artist.image_url} alt={artist.name} />
<h1 onClick={() => handleClick(artist)}>{artist.name}</h1>
<p>Popularity: {artist.popularity}</p>
<p>Genres: {artist.genres}</p>
</div>
))}
</div>
);
}
export default Artists;
TopTracks.js
import React from "react";
import { useLocation } from "react-router-dom";
function TopTracks() {
const location = useLocation();
const tracks = location.state;
return (
<div>
</div>
);
}
export default TopTracks;
Playlists.js and Tracks.js are both just console logging the data like so:
import React from "react";
function Tracks(props) {
const tracks = props.data.tracks.tracks;
console.log(tracks);
return (
<div>
</div>
);
}
export default Tracks;