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
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!!