0

I was building a project connecting it spotify api. I've grabbed the playlist data from the api and set it into a playlists variable but it is not rendering. Below is the whole file for reference.

import { useState, useEffect } from "react"
import useAuth from "./useAuth"
import { Container, ListGroup, ListGroupItem } from "react-bootstrap"
import SpotifyWebApi from "spotify-web-api-node"
import axios from "axios"

const URL = 'https://api.spotify.com/v1/'

const spotifyApi = new SpotifyWebApi({
    clientId: "My_SAMPLE_TOKEN",
})

export default function UserDashboard({ code }) {
    const accessToken = useAuth(code)
    const [user, setUser] = useState()
    const [playlists, setPlaylists] = useState([])
    
    useEffect(() => {
        if (!accessToken) return
        spotifyApi.setAccessToken(accessToken)
    }, [accessToken])

    let Playlists = []
    useEffect(async () => {
        if (!accessToken) return
        const response = await spotifyApi.getMe()
        if (response.statusCode == 200)
            setUser(response.body.display_name)
        console.log(response)
        const response2 = await axios.get(URL + 'me/playlists', {
            headers: {
                Authorization: "Bearer " + accessToken,
            }
        })
        if (response2.status == 200) {
            response2.data.items.forEach(async (l) => {
                const response3 = await axios.get(URL + 'playlists/' + l.id + '/tracks', {
                    headers: {
                        Authorization: "Bearer " + accessToken,
                    }
                })
                Playlists.push({
                    name: l.name,
                    items: response3.data.items
                })
            })
            setPlaylists(Playlists)
            console.log(Playlists)
        }

    }, [accessToken])

    return (
        <Container className="d-flex flex-column py-2" style={{ height: "100vh" }}>
            <div>
                {user}
            </div>
            <div>
                <ListGroup>
                    {playlists.map(p => {
                        <ListGroupItem>
                            <div>{p.name}</div>
                        </ListGroupItem>
                    })}
                </ListGroup>
            </div>
        </Container>
    )
}

I have data in the playlists state variable now but I don't know why it is not rendering on the page.Please let me know on where I'm going wrong.

Zameer Haque
  • 394
  • 4
  • 24
Nik
  • 187
  • 3
  • 17
  • 1
    Does this answer your question? [Using async/await with a forEach loop](https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop) – Gabriele Petrioli Nov 17 '21 at 08:17
  • You should not include your token on public sites like stackoverflow even if its just a trial one. – Zameer Haque Nov 17 '21 at 08:17

1 Answers1

0

You forgot to return the ListGroupItem from the map It should be something like this:

{playlists.map((p) => {
  return (
    <li>
      <div>{p.name}</div>
    </li>
  );
})}

or like this:

{playlists.map((p) => (
  <li>
    <div>{p.name}</div>
  </li>
))}

There are other issues that you might want to address as well:

  • Your useEffect is using async as the function itself, you should define the async function inside the function itself.
  • Don't use forEach with async
  • It's a good idea to use key when iterating over list items (like you do in map) to prevent React giving the wrong component the wrong state.
  • It's better to have some "loading..." stage, instead of rendering undefined user, or an empty list.
  • Use === comparison and not ==
  • And in general when posting on stack overflow, hide secrets, and give a minimal example (No need for react-bootstrap, or your useAuth)

Here's a recreated version of it:

import { useState, useEffect } from "react";
import useAuth from "./useAuth";
import { Container, ListGroup, ListGroupItem } from "react-bootstrap";
import SpotifyWebApi from "spotify-web-api-node";
import axios from "axios";

const URL = "https://api.spotify.com/v1/";

const spotifyApi = new SpotifyWebApi({
  clientId: "8b945ef10ea24755b83ac50cede405a0"
});

export default function UserDashboard({ code }) {
  const accessToken = useAuth(code);
  const [user, setUser] = useState();
  const [playlists, setPlaylists] = useState([]);

  useEffect(() => {
    if (!accessToken) return;

    spotifyApi.setAccessToken(accessToken);
  }, [accessToken]);

  useEffect(() => {
    if (!accessToken) 
      return;

    const fetchData = async () => {
      const response = await spotifyApi.getMe();
      if (response.statusCode === 200) 
        setUser(response.body.display_name);
      
      const response2 = await axios.get(URL + "me/playlists", {
        headers: {
          Authorization: "Bearer " + accessToken
        }
      });
      
      if (response2.status === 200) {
        let list = [];
        for (const item of response2.data.items) {
          const response3 = await axios.get(
            URL + "playlists/" + item.id + "/tracks",
            {
              headers: {
                Authorization: "Bearer " + accessToken
              }
            }
          );
          list.push({
            name: item.name,
            items: response3.data.items
          });
        }
        setPlaylists(list);
      }
    };

    fetchData();
  }, [accessToken]);

  return (
    <Container className="d-flex flex-column py-2" style={{ height: "100vh" }}>
      <div>{user}</div>
      <div>
        <ListGroup>
          {playlists.map((p) => {
            return (
              <ListGroupItem>
                <div>{p.name}</div>
              </ListGroupItem>
            );
          })}
        </ListGroup>
      </div>
    </Container>
  );
}

gilamran
  • 7,090
  • 4
  • 31
  • 50