Jamming Project Help

Hello! I am having some issues with the jamming project. When I click on the search button, I am not rendering search results. I get an error saying,

TypeError: Cannot read property 'map' of undefined
TrackList.render
src/Components/TrackList/TrackList.js:8
   5 | export class TrackList extends React.Component {
   6 |     render() {
   7 |         return (
>  8 |             <div className="TrackList">
   9 |                 {   
  10 |                     this.props.tracks.map(track => {
  11 |                         return <Track onAdd={this.props.onAdd} 

In looking at the Tracklist component, it seems to have been written correctly. In App.js, we start with an initial value of an empty array for the searchResults state. I believe the issue to be that the state of the App component is not updating as it should, thus the map function will not be able to be performed on {this.props.tracks}. Here is the code for app.js :slight_smile:

import React from 'react';
import './App.css';
import {SearchBar} from '../../Components/SearchBar/SearchBar';
import {Playlist} from '../../Components/Playlist/Playlist';
import {SearchResults} from '../../Components/SearchResults/SearchResults';
import {Spotify} from '../../util/Spotify';

export class App extends React.Component {
  constructor(props) {
    super(props)
    this.addTrack = this.addTrack.bind(this);
    this.removeTrack = this.removeTrack.bind(this);
    this.updatePlaylistName = this.updatePlaylistName.bind(this);
    this.savePlaylist = this.savePlaylist.bind(this);
    this.search = this.search.bind(this);

    this.state = {
      searchResults: [],
      playlistName: 'My Playlist',
      playlistTracks: [],
        
    }
  }
  addTrack(track) {
    let playlist = this.state.playlistTracks;
    if  (playlist.some(songObj => songObj.id === track.id)) {
      return
    }
    playlist.push(track);
    this.setState({
      playlistTracks: playlist,
    })
  }
  
  removeTrack(track) {
    let playlist = this.state.playlistTracks;
    playlist = playlist.filter(currentSong => currentSong.id !== track.id)
    this.setState({
      playListTracks: playlist,
    })
  }

  updatePlaylistName(name) {
    this.setState({playlistName: name,})
  }

  savePlaylist() {
    let playlist = this.state.playlistTracks;
    const trackURIs = playlist.map(track => track.uri);
    Spotify.savePlaylist(this.state.playlistName, trackURIs)
    .then(() => {
      this.setState({playlistName: 'New Playlist', playlistTracks: []})
    })
  }
  
      search(term) {
      Spotify.search(term).then(searchResults => {
        this.setState({searchResults: searchResults})
      })
    }


  render() {
    return (
      <div>
      <h1>Ja<span className="highlight">mmm</span>ing</h1>
      <div className="App">
        <SearchBar onSearch={this.search}/>
        <div className="App-playlist">
          <SearchResults  onAdd={this.addTrack} searchResults={this.state.searchResults} />
          <Playlist onRemove={this.removeTrack} 
                    playlistName={this.state.playlistName} 
                    playlistTracks={this.state.playlistTracks}
                    onNameChange={this.updatePlaylistName}
                    onSave={this.savePlaylist} />
        </div>
      </div>
    </div>
    )
  }
}


And for Tracklist.js

import React from 'react';
import './TrackList.css';
import {Track} from '../../Components/Track/Track'

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

and finally, for searchBar.js

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

export class SearchBar extends React.Component {
    constructor(props) {
        super(props);
        this.search = this.search.bind(this);
        this.handleTermChange = this.handleTermChange.bind(this);
        this.state = {
            term: '',
        }
    }
    search() {
        this.props.onSearch(this.state.term)
    }

    handleTermChange(e) {
        this.setState({term: e.target.value});
    }

    render() {
        return (
            <div className="SearchBar">
             <input onChange={this.handleTermChange} placeholder="Enter A Song, Album, or Artist" />
             <button onClick={this.search} className="SearchButton">SEARCH</button>
            </div>
        )
    }
}

Any insight is greatly appreciated!!

1 Like

I actually found the issue for this particular problem. In my Tracklist component, I was iterating over the wrong array. It should have been this.props.tracks.items.map

1 Like

Good work finding the error, and kudos for also coming back and posting the solution. :+1:

1 Like