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;

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.

1 Like

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.

3 Likes