Jammming step 34 TypeError map undefined

https://www.codecademy.com/paths/web-development/tracks/front-end-applications-with-react/modules/jammming/projects/jammming-prj

I have read every single thread regarding the Jammming Project - Step 34! I pay Codecademy to teach me these frameworks however the service has bad teachings! The unstuck video is there to help you get unstuck but the truth is the video causes problems instead of solutions! This has been an issue for many working on this project…

My question is - Why have Codecademy have not updated the video and why a solution has not been given! Plus why have Codecademy not actually taught us this before asking us as newbies to React, to create this project!

My point is i have spent days on trying to resolve this issue like many before me over the past several years - but CODECADEMY have neglected to help with the problem - this is a poor teaching service and i have paid them to teach me not Youtube or any other source! I understand we need to be able to go off and search problems which is not the problem! The video creates a problem due to bad recording and lack of communication… I hope someone can help me resolve this bug!!!

Many thanks,

David

p.s Here is my code

App.js

import React from 'react';
import '../App/App.css';
import SearchBar from '../SearchBar/SearchBar';
import SearchResults from '../SearchResults/SearchResults';
import Playlist from '../Playlist/Playlist';

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      //Hardcoded results for this.state.searchResults containing array of track objects
      searchResults: [{name: 'name1', artist: 'artist1', album: 'album', id: 1},
      {name: 'name2', artist: 'artist2', album: 'album2', id: 2},
      {name: 'name3', artist: 'artist3', album: 'album3', id: 3}],
      playlistName: 'My Playlist',
      playlistTracks: [{name: 'playlistName1', artist: 'playlistArtist1', album: 'playlistAlbum1', id: 4},
      {name: 'playlistName2', artist: 'playlistArtist2', album: 'playlistAlbum2', id: 5},
      {name: 'playlistName3', artist: 'playlistArtist3', album: 'playlistAlbum3', id: 6}]
    }
  }
  render() {
    return (
      <div>
        <h1>Ja<span className="highlight">mmm</span>ing</h1>
        <div className="App">
        <SearchBar />
        <div className="App-playlist">
          {/*Pass the state of the App component’s searchResults to the SearchResults component*/}
        <SearchResults searchResults={this.state.searchResults} />

        {/*inside of Playlist component we pass down the state of playlistName & playlistTracks*/}
        <Playlist playlistName={this.state.playlistName}
        playlistTracks={this.state.playlistTracks} />
    </div>
  </div>
</div>
    )
  }
}

export default App;

Playlist.js

import React from 'react';
import '../Playlist/Playlist.css';
import TrackList from '../TrackList/TrackList';

class Playlist extends React.Component {
    render() {
        return (
            <div className="Playlist">
                <input defaultValue={'New Playlist'}/>

                {/*Here we Pass the playlist tracks from the Playlist component to the TrackList component.*/}
                <TrackList tracks={this.props.playlistTracks} />
                <button className="Playlist-save">SAVE TO SPOTIFY</button>
            </div>
        )
    }
}

export default Playlist;

SearchResults.js

import React from 'react';
import '../SearchResults/SearchResults.css';
import TrackList from '../TrackList/TrackList';

class SearchResults extends React.Component {
    render() {
        return (
            <div className="SearchResults">
                <h2>Results</h2>
                {/*Pass the search results from the SearchResults component to the TrackList component.*/}
                <TrackList tracks={this.props.SearchResults} />
            </div>
        )
    }
}

export default SearchResults;

Track.js

import React from 'react';
import '../Track/Track.css';

class Track extends React.Component {
    
//renderAction() = logic to determine if the Track is already added then display button as - else render button as +
renderAction() {
    if (this.props.isRemoval) {
        return <button className="Track-action">-</button>
    } else {
        return <button className="Track-action">+</button>
    }
}

    render() {
        return (
            <div className="Track">
            <div className="Track-information">
              <h3>{this.props.track.name}</h3>
              <p> {this.props.track.artist} | {this.props.track.album} </p>
            </div>
                {this.renderAction()}
            </div> 
        )
    }
}

export default Track;

TrackList.js

import React from 'react';
import '../TrackList/TrackList.css';
import Track from '../Track/Track';

class TrackList extends React.Component {
    render() {
        return (
            <div className="TrackList">
               {this.props.tracks.map((track) => 
                <Track 
                track={track} 
                key={track.id} />)} 
            
            </div>  
        )
    }
}

export default TrackList;
2 Likes

In your App.js, you’re passing an array from the state to the SearchResults component on a prop named searchResults

But in your SearchResults component, you’re using this.props.SearchResults instead of this.props.searchResults

So the TrackList component receives undefined instead of the array, resulting in your TypeError when using .map() on it.

4 Likes

Dude thank you soooo much for your help!! I made the relevant changes and everything is worting now! I have read soo many docs and threads and you solved it in 3 sentences lol Thanks Again - FYI i was close to smashing my machine up lol

You are a Legend!

1 Like

I dont understand this either, this is day two of trying to figure this out. I found this post today and decided to try to copy this guys code above me to find out if it’s just my code thats messed up. But even after copying it and using it and fixing the this.props. searchResults it still isnt working. I still get the SAME Error. ANy ideas guys???

TypeError: Cannot read property ‘map’ of undefined
TrackList.render
C:/Users/Mark/Desktop/projects/jamming/src/Components/TrackList/TrackList.js:8
5 | class TrackList extends React.Component {
6 | render() {
7 | return (

8 |


9 | {this.props.tracks.map((track) =>
10 | <Track
11 | track={track}

Track.js ```import React from ‘react’;
import ‘…/Track/Track.css’;

class Track extends React.Component {

//renderAction() = logic to determine if the Track is already added then display button as - else render button as +
renderAction() {
if (this.props.isRemoval) {
return -
} else {
return +
}
}

render() {
    return (
        <div className="Track">
        <div className="Track-information">
          <h3>{this.props.track.name}</h3>
          <p> {this.props.track.artist} | {this.props.track.album} </p>
        </div>
            {this.renderAction()}
        </div> 
    )
}

}

export default Track;```

App,js

import '../App/App.css';
import SearchBar from '../SearchBar/SearchBar';
import SearchResults from '../SearchResults/SearchResults';
import Playlist from '../Playlist/Playlist';

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      //Hardcoded results for this.state.searchResults containing array of track objects
      searchResults: [{name: 'name1', artist: 'artist1', album: 'album', id: 1},
      {name: 'name2', artist: 'artist2', album: 'album2', id: 2},
      {name: 'name3', artist: 'artist3', album: 'album3', id: 3}],
      playlistName: 'My Playlist',
      playlistTracks: [{name: 'playlistName1', artist: 'playlistArtist1', album: 'playlistAlbum1', id: 4},
      {name: 'playlistName2', artist: 'playlistArtist2', album: 'playlistAlbum2', id: 5},
      {name: 'playlistName3', artist: 'playlistArtist3', album: 'playlistAlbum3', id: 6}]
    }
  }
  render() {
    return (
      <div>
        <h1>Ja<span className="highlight">mmm</span>ing</h1>
        <div className="App">
        <SearchBar />
        <div className="App-playlist">
          {/*Pass the state of the App component’s searchResults to the SearchResults component*/}
        <SearchResults searchResults={this.state.searchResults} />

        {/*inside of Playlist component we pass down the state of playlistName & playlistTracks*/}
        <Playlist playlistName={this.state.playlistName}
        playlistTracks={this.state.playlistTracks} />
    </div>
  </div>
</div>
    )
  }
}

export default App;

SearchResults.js

import '../SearchResults/SearchResults.css';
import TrackList from '../TrackList/TrackList';

class SearchResults extends React.Component {
    render() {
        return (
            <div className="SearchResults">
                <h2>Results</h2>
                {/*Pass the search results from the SearchResults component to the TrackList component.*/}
                <TrackList tracks={this.props.searchResults} />
            </div>
        )
    }
}

export default SearchResults;```


SearchBar.js ```import React from 'react';
import './SearchBar.css'

 class SearchBar extends React.Component {
    render() {
        return (
            <div className="SearchBar">
  <input placeholder="Enter A Song, Album, or Artist" />
  <button className="SearchButton">SEARCH</button>
</div>
        )
    }
}


export default SearchBar```
PlayList,js 
```import React from 'react';
import './Playlist.css'
import TrackList from '../TrackList/TrackList'

class Playlist extends React.Component {
    render() {
        return (
            <div className="Playlist">
            <input defaultValue={"New Playlist"}/>
            {<TrackList />}
            <button className="Playlist-save">SAVE TO SPOTIFY</button>
          </div>
        )
    }
}



export default Playlist

TrackList.js

import '../TrackList/TrackList.css';
import Track from '../Track/Track';

class TrackList extends React.Component {
    render() {
        return (
            <div className="TrackList">
               {this.props.tracks.map((track) => 
                <Track 
                track={track} 
                key={track.id} />)} 
            
            </div>  
        )
    }
}

export default TrackList;```

You definitely haven’t copied all the files from the OP. Notice that in the Playlist component, you aren’t passing any props to the TrackList component. This means that when the Playlist tries to render, it uses a TrackList component without an array of tracks, then the TrackList component tries to use the .map() method. Since nothing was passed to it, it tries to use .map() on undefined.

The big issue with Step 34 is that it breaks the app for awhile. The Playlist component doesn’t get fully hooked up with the data until completing the steps up to and including Step 39. You should continue until that step and only worry about errors after that.

5 Likes

Thank you so much… this was driving me nuts as well

1 Like

You solved it for me! Thank you so much - I replaced my Tracklist component in the Playlist component with a comment to say the tracklist should go here, and it worked!

Thank you so much!!! I don’t know how I could ever move on with the steps if there is a problem though haha.

I’ve been following up until step 34 and the website turned empty as soon as I added this in TrackList.js

{
                    this.props.tracks.map(track => {
                        return <Track track={track} key={track.id} />
                    })
}

Commenting it out would show the website back again. wondering what’s wrong.

The <TrackList /> component is used in TWO places, the <SearchResults /> and <Playlist /> components.

Step 34 updates the <TrackList /> component to extract information from the props passed down to it - in this case when it is rendered by <SearchResults />.
However, this modification breaks the app because, at this stage, no information is being passed down to the <TrackList /> component rendered by <Playlist />. So it attempts to extract information from ‘undefined’ and breaks.

This drove me nuts until I read this elegant solution.

2 Likes

I was following the video for help because I couldn’t figure out why after step 34 I was getting a blank screen instead of the app showing properly.
Turns out it was basically what you are pointing out. <TrackList /> being used in two places.
Once I commented out <TrackList /> in <Playlist /> everything displayed just fine.

I know this particular project has received a lot of hate both in the forums and on the YouTube walkthrough, but it really is the worst project I’ve come across so far in regard to how it’s laid out, the lessons prior to the project not really preparing you for what the project involves, and the poorly put together walkthrough video.

I’m glad you pointed out how having the component in two places breaks the page, because I don’t know that I would have figured that out on my own and I had stopped trying to move forward with the project the last several days as I tried to figure out what was causing the problem.

:pray:Thank you SO much! This is all I needed to do!

Honestly, I just ended up basically verbatim copying the tutorial video code because this exercise vs what I’ve been taught up until this exercise, are miles apart. I’ve loved every section of the curriculum until this. Serious updating needs to be done here.

IF YOU ARE STUCK HERE. JUST BASICALLY SKIP IT, WHILE GETTING THE GIST AND MOVE ON TO HOOKS. THAT’S WHAT YOU’LL BE USING THE MOST ANYWAY.