I'm currently making a presentation feature with songs included in it.
I'm getting an error of listedSongs.map is not a function
in this code. I am using the map function in GetSongsRequest to add the songs into a div. This is working fine.
The thing that is failing is the map function in SongsInList and I'm not quite sure why because the map functions are almost identical except I have had to raise the state of listedSongs so it is accessible to both functions.
import React, {useState, useEffect} from "react"
import { useAuth0 } from "@auth0/auth0-react";
function GetSongsRequest(listedSongs, addListedSongs) {
const { user } = useAuth0();
const [songs, setSongs] = useState([])
useEffect(() => {
if (user) {
const requestOptions = {
method: 'GET'
};
let url = '#' + user.sub
fetch(url, requestOptions)
.then(response => {
return response.json();
}).then(jsonResponse => {
setSongs(jsonResponse)
localStorage.setItem('songsStorage', JSON.stringify(jsonResponse))
}).catch (error => {
console.log(error);
})
}
}, [user])
return (
<>
<ul>
{songs.map((el) => (
<li key={el} className="tailwindCssStuff"
onClick={ () => addListedSongs(listedSongs.concat(el)) }>
{el[0]}</li>
))}
</ul>
</>
)
}
function SongsInList(listedSongs) {
return (
<ul>
{listedSongs.map((el) => (
<li key={el} className="tailwindCssStuff">
{el[0]}</li>
))}
</ul>
)
}
export default function Main() {
const [listedSongs, addListedSongs] = useState([])
return (
<div>
<div id="userContent" className="tailwindCssStuff">
<h1 className="tailwindCssStuff">Songs</h1>
<div id = "vertical-content">
<GetSongsRequest listedSongs={listedSongs} addListedSongs={addListedSongs} />
</div>
</div>
<div id="liveList" className="tailwindCssStuff">
<h1 className="tailwindCssStuff">List</h1>
<div id = "vertical-list">
<SongsInList listedSongs={listedSongs} />
</div>
</div>
</div>
)
}
[["Song","LINE 1\nLINE 2\nLINE 3\nLINE 4"],["Song 2","LINE 1\nLINE 2\nLINE 3\nLINE 4"],["Song 3","LINE 1\nLINE 2\nLINE 3\nLINE 4"],["Song 4","LINE 1\nLINE 2\nLINE 3\nLINE 4"],["Song 5","LINE 1\nLINE 2\nLINE 3\nLINE 4"],["SONG 6","SEDTRFGYUHIJ\nRXDGYUIHJO\nRDFTGYUHIJOKP\nJRCFGVHBJN"]]
This is an example of what I would get from the GET request
Thanks!
Assuming the data fetching at state updates are correct, you've a few issues with props handling.
GetSongsRequest
needs to access the props correctly. Resolve this by destructuring from the props object.
import React, { useState, useEffect } from "react";
import { useAuth0 } from "@auth0/auth0-react";
function GetSongsRequest({ listedSongs, addListedSongs }) {
const { user } = useAuth0();
const [songs, setSongs] = useState([])
useEffect(() => {
if (user) {
const requestOptions = {
method: 'GET'
};
let url = '#' + user.sub
fetch(url, requestOptions)
.then(response => {
return response.json();
}).then(jsonResponse => {
setSongs(jsonResponse)
localStorage.setItem('songsStorage', JSON.stringify(jsonResponse))
}).catch (error => {
console.log(error);
})
}
}, [user])
return (
<ul>
{songs.map((el) => (
<li key={el} className="tailwindCssStuff"
onClick={ () => addListedSongs(listedSongs.concat(el)) }>
{el[0]}</li>
))}
</ul>
)
}
Similarly, SongsInList
needs to destructure the listedSongs
props which is the array you want to map.
function SongsInList({ listedSongs }) {
return (
<ul>
{listedSongs.map((el) => (
<li key={el} className="tailwindCssStuff">
{el[0]}
</li>
))}
</ul>
)
}
Main is ok.
export default function Main() {
const [listedSongs, addListedSongs] = useState([])
return (
<div>
<div id="userContent" className="tailwindCssStuff">
<h1 className="tailwindCssStuff">Songs</h1>
<div id = "vertical-content">
<GetSongsRequest listedSongs={listedSongs} addListedSongs={addListedSongs} />
</div>
</div>
<div id="liveList" className="tailwindCssStuff">
<h1 className="tailwindCssStuff">List</h1>
<div id = "vertical-list">
<SongsInList listedSongs={listedSongs} />
</div>
</div>
</div>
)
}