Jamming Project: The Search and Save Button Problem

Hello, I’m Karina!

I need help for my project (Web Developing). So the case is, i’ve already finished all the 99 steps, and think i did it all right (no errors and any warnings), BUT !! On my “ready site” when I’m writing in the searchbar names of Artists and clicking “Search” the “Result” don’t work, nothing appears…also the same with “Save to Spotify”.
What I did wrong?

My project’s site: http://dreary-sack.surge.sh/

My Project’s Spotify.js: ```
const clientId = ‘’;
const redirectUri = ‘http://dreary-sack.surge.sh’;

let accessToken;

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 {
		const accessUrl = `https://accounts.spotify.com/authorize?client_id=${clientId}_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,
			artist: track.artist[0].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(`https://api.spotify.com/v1/users/${userId}/playlists`, {
			headers: headers,
			method: 'POST',
			body: JSON.stringify({
				name: name
			})
		}).then(response => response.json()).then(jsonResponse => {
			const playlistId = jsonResponse.id;
			return fetch(`http://api.spotify.com/v1/users/${userId}/playlists/${playlistId}/tracks`, {
				headers: headers,
				method: 'POST',
				body: JSON.stringify({
					uris: trackUris
				})
			})
		})
	});

}

}

export default Spotify

Hello. I figured out why you have this problem. In SearchBar.js, you need to add onClick={this.search} to the SEARCH button element.

And also, in your Spotify.js, you have this line:

const clientId = ‘’; //value removed by moderator

You should NEVER share your client id’s, api keys, or anything else you don’t want compromised on the forums.

P.S. You can edit your post and delete that line, or you can edit it to say:

const clientId = redacted ( not published )

Also, for future reference when putting code in posts:
https://discuss.codecademy.com/t/how-to-ask-good-questions-and-get-good-answers/77980

(Scroll down until you see the Formatting Code section)

2 Likes

Good advice!! I removed the value from both posts.

1 Like

Thanks for the answer!

I did as you said, but, unfortunately, it doesn’t work, now by clicking the “Search”, the site gets blank white and “response_type must be code or token” appears. :cry:

My App.js:

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) {
		let tracks = this.state.playlistTracks;
		if (tracks.find(savedTrack =>
				savedTrack.id === track.id)) {
			return;
		}
		tracks.push(track);
		this.setState({
			playlistTracks: track
		})
	}

	removeTrack(track) {
		let tracks = this.state.playlistTracks;
		tracks = tracks.filter(currentTrack => currentTrack.id !== tracks.id);

		this.setState({
			playlistTracks: tracks
		});
	}

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

	savePlaylist() {
		const trackUris = this.state.playlistTracks.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</h
			1 >
			<
			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;

Hmmm. I have had the same problem with the jammming project! So I don’t actually know how to solve this?!!!

1 Like

I don’t think you should be putting spaces between your prop assignments. like on

			Playlist playlistName = {
				this.state.playlistName
			}
			playlistTracks = {
				this.state.playlistTracks
			}
			onRemove = {
				this.removeTrack
			}
			onNameChange = {
				this.updatePlaylistName
			}
			onSave = {
				this.savePlaylist
			}
			/>

just as an example

onSave={this.savePlayist}

Hi!

I didn’t do that, it’s bc of the JS beautifizer.
But thanks for your advise :grinning:

Wow I guess I just need more time coding. It would be amazing if everything in code could look the same and be the way I recognize it. I don’t like the way JS beautifier did that. Have you figured out what you did wrong yet? I just finished this entire exercise.

Not sure if it matters but in my project I have a / at the end of my const redirectUri.

in your code I see

const redirectUri = ‘http://dreary-sack.surge.sh’;

I would change to

const redirectUri = ‘http://dreary-sack.surge.sh/’;

make sure to update your dashboard in spotify with the correct redirectUri. Also make sure to run
npm run build
to get the changes pushed over to your build directory before you republish the site.

1 Like

Did everything as you said, but it didn’t work ((((

your accessURL in the else clause of getAccessToken() is wrong. If you want the direct answer I can give but go back and try to find yourself. you’re really close.

Tell me please! It’s turning me already crazy :roll_eyes:

sure no problem. Just figured you were so close you might want to give it another shot. The correct line of code is

const accessUrl = `https://accounts.spotify.com/authorize?client_id=${clientId}&response_type=token&scope=playlist-modify-public&redirect_uri=${redirectUri}`;

you left out the &response before the _type. my guess is you accidentally deleted it while trying to update the clientId in the interpolation string.

1 Like

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.