Hi all,
Can anyone confirm if the Jamming project works for users other than yourself?
I completed the project and got it running successfully for myself.
However, when the app is accessed frommy boyfriend’s spotify account, it errors out when trying to search.
Here is the CodeCademy project page;
https://www.codecademy.com/paths/front-end-engineer-career-path-21/tracks/fecp-react-part-ii/modules/fecp-challenge-project-jammming/projects/jammming-prj
What I tried;
- Open Chrome incognito mode
- Access the url I hosted my website at
- When prompted, log into my spotify account
- Try to search something ( & then add it to playlist)
When I log in with my own spotify credentials, this works fine.
However, if I;
5) Close that browser window, re-open incognito mode & have my boyfriend repeat the above steps on his own spotify account.
It will error out when he tries to search something from his own account.
Is there any reason why this may be happening?
I can see the console is generating different access tokens for us both, if this is relevant.
My app, hosted online;
My app.js;
import React from 'react';
import './App.css';
import SearchResults from './../SearchResults/SearchResults.js'
import Playlist from './../Playlist/Playlist.js'
import SearchBar from './../SearchBar/SearchBar.js';
import Spotify from './../util/Spotify.js';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
searchResults : [
// {"id": 1, "name": "One True Love", "artist": "Jordan", "album": "Miss U Baby" },
// {"id": 2, "name": "Favourite Honey", "artist": "DJ Robin", "album": "Never Look Back" },
// {"id": 3, "name": "Perfect", "artist": "TT Beats", "album": "Actions Not Words" }
],
playlistName : "New Playlist",
playlistTracks : [
// {"id": 4, "name": "song1", "artist": "Jordeen", "album": "Miss U Boby" },
// {"id": 5, "name": "song2", "artist": "DJ Robeen", "album": "Never Look Bk" },
// {"id": 6, "name": "song3", "artist": "TT Beatzz", "album": "Actions Not Wordzz" }
]
};
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);
}
render() {
return (
<div>
<h1>Ja<span className="highlight">mmm</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>
);
}
componentDidMount() {
window.addEventListener('load', () => {Spotify.getAccessToken()});
}
addTrack(track) {
const currentPlaylist = this.state.playlistTracks;
const isSame = currentPlaylist.some(existingTrack => existingTrack.id === track.id);
if (isSame === false) {
currentPlaylist.push(track);
this.setState({playlistTracks : currentPlaylist});
}
}
removeTrack(track) {
const currentPlaylist = this.state.playlistTracks;
const newPlaylist = currentPlaylist.filter(existingTrack => existingTrack.id !== track.id);
this.setState({playlistTracks : newPlaylist });
}
updatePlaylistName(newName) {
this.setState({playlistName : newName});
}
savePlaylist() {
const trackURIs = this.state.playlistTracks.map(track => track.uri);
Spotify.savePlaylist(this.state.playlistName, trackURIs);
this.setState({playlistName : 'New Playlist'});
this.setState({playlistTracks : []})
}
search(searchParameter) {
Spotify.search(searchParameter).then(searchResults => {
this.setState({searchResults : searchResults})
})
}
}
export default App;
My Spotify.js;
(I removed the lines that console.log the access token/ expires in. as per the console screenshots)
let accessToken;
const client_id = 'a038457604634aac9a912fff8748b31d';
const redirect_uri = 'https://pzakeri22.github.io/spotify_playlist_app';
const Spotify = {
async authorise() {
let endpoint = this.getEndpoint();
try {
const response = await fetch(endpoint);
if (response.ok) {
const jsonResponse = await response.json();
return jsonResponse;
}
throw new Error('Request Failed!');
} catch (error) {
console.log(error);
}
},
async search(searchTerm) {
const accessToken = Spotify.getAccessToken();
const headers = {
headers: {Authorization: `Bearer ${accessToken}`}
}
try {
const response = await fetch(`https://api.spotify.com/v1/search?type=track&q=${searchTerm}`, headers);
if (response.ok) {
const jsonResponse = await response.json();
if (!jsonResponse.tracks) {
return [];
} else {
return jsonResponse.tracks.items.map(track => ({
id: track.id,
name: track.name,
artist: track.artists[0].name,
album: track.album.name,
uri: track.uri
}));
}
}
throw new Error('Request Failed!');
} catch (error) {
console.log(error);
}
},
getAccessToken() {
if (accessToken) {
return accessToken;
} else {
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, '/');
console.log(accessToken);
console.log(expiresIn);
return accessToken;
} else {
const accessUrl = `https://accounts.spotify.com/authorize?client_id=${client_id}&response_type=token&scope=playlist-modify-public&redirect_uri=${redirect_uri}`;
window.location = (accessUrl);
}
}
},
savePlaylist(playlistName, trackURIs) {
if (!playlistName || !trackURIs) {
return;
}
const accessToken = Spotify.getAccessToken();
const headers = {Authorization: `Bearer ${accessToken}`};
let userID;
let playlistID;
async function asyncGetID() {
const response = await fetch(`https://api.spotify.com/v1/me`, {
headers: headers
})
let jsonResponse;
if (response.ok) {
jsonResponse = await response.json();
}
else {
throw new Error(`Request Failed! ${response.status}, ${response.message}`);
}
userID = jsonResponse.id;
}
async function asyncCreatePlaylist() {
const response = await fetch(`https://api.spotify.com/v1/users/${userID}/playlists`, {
headers: headers,
method: 'POST',
body: JSON.stringify({name: playlistName})
});
if (response.ok) {
const jsonResponse = await response.json();
playlistID = jsonResponse.id;
} else {
throw new Error(`Request failed! ${response.status}, ${response.message}`);
}
}
async function asyncUpdatePlaylist() {
//online it looks like endpoint is `https://api.spotify.com/v1/playlists/${playlistID}/tracks` but i will use what codecademy said
const response = await fetch(`https://api.spotify.com/v1/users/${userID}/playlists/${playlistID}/tracks`, {
headers: headers,
method: 'POST',
body: JSON.stringify({uris: trackURIs})
});
if (response.ok) {
return;
}
throw new Error(`Request failed! ${response.status}, ${response.message}`);
}
async function save() {
try {
await asyncGetID();
await asyncCreatePlaylist();
await asyncUpdatePlaylist();
} catch (error) {
console.log(error);
}
}
save();
}
}
export default Spotify;
Here are the errors in the console on my boyfriend’s account after searching;
Thanks,