Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

React map not a function

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>
    )
}
  • Example Data:
[["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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Thanks!

>Solution :

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>
  )
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading