I’m having trouble with the ‘Feature Request’ advanced project (building on the Jammming project)n - hope someone can help me out
This is what I am trying to achieve:
Base code - which works - from the original jammming project
WIP edited code for Feature Request - breaks the website
Errors in console
On loading the site, I get this warning:
index.js:1 Warning: Playlist contains an input of type undefined with both value and defaultValue props. Input elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://reactjs.org/link/controlled-components
After having used the app (search, logged into Spotify, added tracks to playlist, edited playlist name, and HIT “Save to spotify button”, this is when the whole website breaks with an error message in browser and console:
Uncaught TypeError: Cannot read property 'then' of undefined
at App.savePlaylist (App.js:51)
This error message is repeated twice in console.
EDIT: For clarity: while the website breaks (unusable: error) - the app does save the playlist to the user’s spotify account before the website breaks.
Code snippets (see above links if want more)
App.js
savePlaylist() {
console.log(`line 45 App.js`); //printing - before error
let trackUris = this.state.playlistTracks.map((track) => track.uri);
console.log(`line 47 App.js ${trackUris}`); // printing before error
if (trackUris && trackUris.length) {
console.log(`line 49 App.js ${trackUris} and ${trackUris.length} and ${this.state.playlistName}`); //printing before error
// below line is the problem 'Uncaught TypeError Cannot read property 'then' of undefined
Spotify.savePlayList(this.state.playlistName, trackUris).then(() => {
console.log(`line 52 App.js ${trackUris}`); //not printing
this.setState({
playlistName: "New Playlist Name",
playlistTracks: [],
});
});
} else {
alert("Your playlist is empty! Please add tracks.");
}
}
The only code I’ve significantly altered from the working code of the main Jammming project is in the ./src/util/Spotify.js file where I refactored Spotify.savePlayList() to separate the getting of the userId into new Spotify.getCurrentUserId() method.
I didn’t get any further in my Feature Request plan than this step.
There have been minor changes to run the code locally on localhost:3000 (when I’d previously changed the homepage and redirectUri to be the web address of the GitHub pages deployment).
getCurrentUserId() {
if (userId) {
return userId;
}
const accessToken = Spotify.getAccessToken();
const headers = {
Authorization: `Bearer ${accessToken}`,
};
return fetch("https://api.spotify.com/v1/me", {
headers: headers,
})
.then((response) => response.json())
.then((jsonResponse) => {
userId = jsonResponse.id;
console.log(`line 45 ${userId}`); //prints after error messages
return userId;
})
.catch(function (err) {
console.log("Fetch problem line 49: " + err.message); //doesn't print
});;
},
savePlayList(name, trackUris) {
if (!name || !trackUris.length) {
return;
}
const accessToken = Spotify.getAccessToken();
const headers = {
Authorization: `Bearer ${accessToken}`,
};
Spotify.getCurrentUserId().then((response) => {
userId = response;
console.log(`line 91 ${userId}`); // prints after error messages
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;
console.log(`line 100 ${playlistId}`); //prints after error messages
return fetch(
`https://api.spotify.com/v1/users/${userId}/playlists/${playlistId}/tracks`,
{
headers: headers,
method: "POST",
body: JSON.stringify({ uris: trackUris }),
}
);
})
.catch(function (err) {
console.log("Fetch problem: " + err.message); //doesn't print
});
});
},
Troubleshooting
I have read other posts here on codecademy and searched online, and the closest similarity that I can find to my problem is to this post - which suggests it may be a return issue, but I can’t see where I would need to put another return.
Throughout my code I have used console.log to identify what is and isn’t running and logging.
- logs App.js lines 45, 47, and 49 fine, testing trackUris, trackUris.length, and this.state.playlistName
- error is hit at App.js line 51, and line 52 doesn’t log
- after the error is thrown, Spotify.js lines 48, 91 and 100 are logged, with userId and playlistId
- I have tried a few tweaks after reading other info - adding and removing ‘return’ statements, reordering the promise/then chain, and calling of methods. It’s hard to know if I fixed one thing and broke another!
Thanks for any advice you can give.