Jammin SearchBar only yields results with the word 'Object' in the name

Here’s a link to the jammin project I’m having an issue with: Jammmin project

I’ve completed the project and had the notorious issue with the Search Button and added the onClick features. Worked fine and renders results but somehow it ALWAYS renders the same results. ALL of the results have the word OBJECT in them so I think somewhere I’ve messed up and only the inputs TYPE is being searched, which is object. Any ideas?

I’ve only added the SearchBar.js, App.js and Spotify.js for readability as I’m positive that the issue is somewhere in there.

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

class SearchBar extends React.Component{
    constructor(props){
        super(props);
        this.search = this.search.bind(this);
        this.handleTermchange = this.handleTermchange.bind(this);
    }

    search(){
        this.props.onSearch = this.state.term;
    }

    handleTermchange(event){
        this.setState({term: event.target.value})
    }
    render(){
        return ( 
            <div className="SearchBar">
  <input placeholder="Enter A Song, Album, or Artist" onChange={this.handleTermchange}/>
  <button className="SearchButton" onClick={this.props.onSearch}>SEARCH</button>
</div>
        )
    }
}
import React from 'react';
import './App.css';

import SearchBar from '../SearchBar/SearchBar';
import SearchResults from '../SearchResults/SearchResults'
import Playlist from '../Playlist/playlist'

import Spotify from '../../util/Spotify'


class App extends React.Component{
  constructor(props){
    super(props);
      
         
      this.state = {
        searchResults: [],
        playlistName: 'My Playlist',
        playlistTracks: []
      }

      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);

  }

    addTrack(track){
      const tracks = this.state.playlistTracks;
      if (tracks.find(savedTrack => savedTrack.id === tracks.id)) {
        return;
      }
      tracks.push(track);
      this.setState({playlistTracks: tracks})
    }

    removeTrack(track){
      let tracks = this.state.playlistTracks
      if (tracks.filter(savedTrack => savedTrack.id !== tracks.id)) {
        return;
      }
      tracks.pop(track);
        this.setState({playlistTracks: tracks})
    }

    updatePlaylistName(name){

       this.setState({ playlistName: name })
    }

    savePlaylist(){
      Spotify.savePlaylist();
      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"></span>ing</h1>
  <div className="App">
    <SearchBar onSearch={this.search}/>
    <div className="App-playlist">
      <SearchResults searchResults={this.state.searchResults} 
                      onAdd={this.addTrack}/>
      <Playlist playlistName={this.state.playlistName} 
                playlistTracks={this.state.playlistTracks}
                onRemove={this.removeTrack} 
                onNameChange={this.updatePlaylistName}
                onSave={this.savePlaylist}/>
      
    </div>
  </div>
</div>
    )
  }
}



export default App;

Client id has been removed for obvious security reason. but here’s spotify.js

const { default: SearchBar } = require("../components/SearchBar/SearchBar")
const { default: Track } = require("../components/Track/Track")

let accessToken;
const CLIENT_ID = ''
const redirectUri = 'http://localhost:3000/'



const Spotify = {

    getAccessToken(){
        if (accessToken){
            return accessToken
        }
        const accessTokenMatch = window.location.href.match(/access_token=([^&]*)/);
        const expiresInMatch = window.location.href.match(/expires_in=([^&]*)/);
        
        if (accessTokenMatch && expiresInMatch){
            accessToken = accessTokenMatch[1];
            const expiresIn = Number(expiresInMatch[1]);
            window.setTimeout(() => accessToken = '', expiresIn * 1000);
            window.history.pushState('Access Token', null, '/');
            return accessToken;
        }else{
        
        // attemping to use spotify's redirect_uri setting instead of my own variable
        // may need to set 'REDIRECT_URI' in the below url to a variable.
        
            const accessUrl = `https://accounts.spotify.com/authorize?client_id=${CLIENT_ID}&response_type=token&scope=playlist-modify-public&redirect_uri=${redirectUri}`
            window.location = accessUrl
        }
    },

    search(term){

        const accessToken = Spotify.getAccessToken();

        return fetch(`https://api.spotify.com/v1/search?type=track&q=${term}`, {
            headers: { Authorization: `Bearer ${accessToken}`}
        }).then(response => {
            return response.json();
        }).then(jsonResponse => {
            if (!jsonResponse.tracks) {
                return [];
            }
            return jsonResponse.tracks.items.map(track => ({
            id: track.id,
            name: track.name,
            artists: track.artists[0].name,
            album: track.album.name,
            uri: track.uri
            })
            )

        })
    },

    savePlaylist(name, trackUris){
        if (!name || !trackUris.length){
          return;
        }
        const accessToken = Spotify.getAccessToken();
        const headers = {Authorization: `Bearer ${accessToken}`}
        let userID;

        return fetch('https://api.spotify.com/v1/me', {headers: headers}).then(response => {
            response.json();
        }).then(jsonResponse => {
            userID = jsonResponse.id
            return fetch(`/v1/users/{user_id}/playlists`, {
                headers: headers,
                method: 'POST',
                body: JSON.stringify({ name: name })
            }).then(response => response.json()
            ).then(jsonResponse => {
                const playlistId = jsonResponse.id;
                return fetch( `https://api.spotify.com/v1/users/${userID}/playlists/${playlistId}/tracks`, 
                {
                    headers: headers,
                    method: 'POST',
                    body: JSON.stringify({
                    uris: trackUris
                    })
                })
            })
        })
      }
     
    
}

export default Spotify;

Your immediate issues are in the SearchBar.js file.

You need to revisit how you added the onClick features to the Search button. Right now you’re having the click event immediately call the function that is in the props, which was passed in from App.js. The click will send the event object to the function.

Click if you need a hint about fixing this

You have a search() function in your SearchBar.js file that you aren’t calling at all. This is supposed to be what your button calls.

Once you do resolve that issue, you’ll need to tackle the error message that comes.

Click if you need a hint about how to fix the next issue

Since you’re now using this.search for the click event of your Search button, you’ll need to fix this function.

this.props.onSearch is a function that was passed in from App.js, but you’re currently trying to set it’s value with =. Call it like a function with the search term.

Thanks! I also had forgotten to set the default state to and empty string for the term parameter in the constructor. Working great now. Corrected code below with notes.

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

class SearchBar extends React.Component{
    constructor(props){
        super(props);
//added this.state setting term to and empty string
        this.state = {
            term: ''
        }

        this.search = this.search.bind(this);
        this.handleTermChange = this.handleTermChange.bind(this);
    }
//onSearch now called like a function rather than using the = assignment operator
    search(term){
        this.props.onSearch(this.state.term);
    }

    handleTermChange(event){
        this.setState({ term: event.target.value })
    }
    render(){
        return ( 
            <div className="SearchBar">
  <input placeholder="Enter A Song, Album, or Artist" onChange={this.handleTermChange}/>
//the onClick property now references the search function in this component rather than calling this.props.onSearch from App.js
  <button className="SearchButton" onClick={this.search}>SEARCH</button>
</div>
        )
    }
}
export default SearchBar;