Reputation: 92
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!
Upvotes: 1
Views: 1198
Reputation: 17
The issue here is the way you are reading props
for the GetSongsRequest
and SongsInList
components.
Functional components do get the props as the first parameter (check react docs)
You can use:
function SongsInList(props) {
return <ul>
{ props.listedSongs.map( ... ) }
</ul>
}
Or either make an object destruction in the function parameters:
function SongsInList({ listedSongs }) {
return ...
}
function GetSongsRequest({ listedSongs, addListedSongs }) {
return ...
}
Upvotes: 0
Reputation: 202836
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>
)
}
Upvotes: 2