Hi everyone!
I have just finished the Jammming project, but I’m facing a very annoying issue:
Every time I search for something and click on ‘Search’, I’m automatically shown a Spotify screen asking me to accept their conditions, I accept them, and then I’m brought back again to the Jammming screen with an empty searchbar. I’m stucked in some kind of loop.
Any help will be very appreciated
You can access to it here: HTTP://marinabir94.surge.sh
Spotify.js :
let token;
let expiresIn;
const clientID = "{my_private_clientID}";
const redirectURI = "http://marinabir94.surge.sh";
const Spotify = {
getAccessToken() {
if (token) {
return token;
}
//check access token match.
const tokenMatch = window.location.href.match(/access_token=([^&]*)/);
const expirationMatch = window.location.href.match(/expires_in=([^&]*)/);
if (tokenMatch && expirationMatch) {
token = tokenMatch[1];
expiresIn = Number(expirationMatch[1]);
//This clears the parameters, allowing us to grab a new access token when it expires
window.setTimeout(() => token = '', expiresIn * 1000);
window.history.pushState('Access Token', null, '/');
return token;
} else {
window.location = `https://accounts.spotify.com/authorize?client_id=${clientID}&response_type=code&redirect_uri=${redirectURI}`;
}
},
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,
}));
});
},
savePlaylist(playlistName, arrURIs) {
if (!playlistName || !arrURIs.length) {
return;
}
const accessToken = Spotify.getAccessToken();
const headers = {Authorization: `Bearer ${accessToken}`};
let userID;
let playlistID;
//GET - Return user's ID
return fetch(`https://api.spotify.com/v1/me`, {headers : headers}
).then(response => response.json()
).then(jsonResponse => {
userID = jsonResponse.id;
//POST - We use the userID to create a Playlist ID
return fetch(`https://api.spotify.com/v1/users/${userID}/playlists`,
{
headers : headers,
method : 'POST',
body : JSON.stringify({
name : playlistName,
description: 'New playlist description',
public: false})
}
).then(response => response.json()
).then(jsonResponse => {
playlistID = jsonResponse.id;
//POST - We use the Playlist ID to upload tracks to that playlist
return fetch(`https://api.spotify.com/v1/users/${userID}/playlists/${playlistID}/tracks`,
{
header : headers,
method : 'POST',
body : JSON.stringify({
uris : arrURIs
})
});
})
});
},
componentDidMount() {
window.addEventListener('load', () => {Spotify.getAccessToken()});
}
};
export default Spotify;
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 "../../utils/Spotify";
//import { render } from "@testing-library/react";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
searchResults: [],
playlistName: "New 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);
}
//Click handler
addTrack(track) {
let currentTracks = this.state.playlistTracks;
if (currentTracks.includes(track.id)) {
return;
} else {
currentTracks.push(track);
this.setState({ playlistTracks: currentTracks });
}
}
//Click handler
removeTrack(track) {
let currentTracks = this.state.playlistTracks;
currentTracks = currentTracks.filter((item) => item.id !== track.id);
this.setState({ playlistTracks: currentTracks });
}
updatePlaylistName(name) {
this.setState({ playlistName: name });
}
//Needs an array of URIs to be sent to the API GET method.
savePlaylist() {
const trackURIs = this.state.playlistTracks.map((track) => track.uri);
Spotify.savePlaylist(this.state.playlistName, trackURIs).then(() => {
//After sending the POST, we restore the default values
this.setState({
playlistName: "New Playlist",
playlistTracks: [],
});
});
}
search(term) {
Spotify.search(term).then(results => {
this.setState({ searchResults: results });
})
}
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}
/>
</div>
</div>
</div>
);
}
// componentDidMount() {
// window.addEventListener('load', () => {Spotify.getAccessToken()});
// }
}
export default App;