Welp, I’m particularly stumped on this one. This project has me feeling pretty dumb considering the sheer amount of Javascript logic you were expected to know off hand without desperately following along with the walkthrough. I did pretty well right up to the very end, but for whatever reason my searches will not go through. I keep getting a ‘Missing required parameter: client_id’ error code when I attempt to hit the search button.
Also, for what it’s worth, I cannot for the life of me find the step that tells me to add an ‘onCilck’ prop to the rendered in . Nothing happens if you click the button without it, but for some reason the walkthrough video and the instructions seems to skip this step but it works for him anyway. Attached is the code for Spotify.js and SearchBar.js, the answer has to be somewhere in here but I’ve been beating my head against the wall for two full days stuck up on it. Help!
Spotify.js:
let accessToken;
const clientId = //My client Id is here and 100% correct
const redirectUri = 'http://localhost:3000/';
const Spotify= {
getAccessToken() {
if(accessToken) {
return accessToken;
}
// check for acces token match
const accessTokenMatch = window.location.href.match(/access_token=([^&]*)/);
const expiresInMatch = window.location.href.match(/expires_in=([^&]*)/);
if(accessTokenMatch && expiresInMatch) {
let 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}&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,
artist: 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(`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(`https://api.spotify.com/v1/users/${userId}/playlists/${playlistId}/tracks`, {
headers: headers,
method: 'POST',
body: JSON.stringify({ uris: trackUris })
})
})
})
}
};
export default Spotify;```
SearchBar.js:
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(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} />
SEARCH
);
}
};
export default SearchBar;