I've been trying to figure out what's the correct way or the best practice in terms of working with Async requests and observables, but I cannot seem to find something that is straightforward. Also, there's a lot of stuff out there that suggest using Promises instead of Observables, but I read that Observables are much more flexible to deal with. So I want to continue working with Observables.
So basically, the functions in my service class looks like this.
getUserTop(spotifyRequestType, timeRange, resultLimit): Observable<any>{
return this.httpClient.post<Observable<any>>('http://localhost:3000/getUserTop', {
spotifyRequestType: spotifyRequestType, //artist or track
timeRange: timeRange, //between short_term, medium_term, long_term
resultLimit: resultLimit //number of results to be displayed
}).pipe(catchError(this.handleError));
}
getRecommendations(seed_artists):Observable<any> {
return this.httpClient.post<Observable<any>>('http://localhost:3000/getRecommendations',
{
seed_artists : seed_artists
}
).pipe(catchError(this.handleError));
}
createPlaylist(playlistName, playlistDesc, isPublic, tracks): Observable<any>{
return this.httpClient.post<Observable<any>>('http://localhost:3000/createPlaylist', {
playlistName: playlistName, //name of the playlist
playlistDesc: playlistDesc, //desc of the playlist
isPublic: isPublic, //public or private indicator
tracks: tracks //tracks to be added to the playlist
}).pipe(catchError(this.handleError));
}
I'm running an Node.js server on localhost:3000. The get functions simply get JSON objects from the Node
- Get top artists.
- Get recommended tracks based on artists.
- Create playlist and add tracks.
These are my methods.
getTopArtists(spotifyRequestType, timeRange, resultLimit): String {
var artistList = '';
this.spotifyService.getUserTop(spotifyRequestType, timeRange, resultLimit).subscribe(
data => {
for(var i=0; i<data['items'].length; i++ ){
artistList += data['items'][i]['id'];
}
}
)
return artistList;
}
getRecommendations(artist): String[]{
var trackList = [];
this.spotifyService.getRecommendations(artist).subscribe(
data => {
for(var i=0; i<data['items'].length; i++ ){
trackList.push(data['items'][i]['id']);
}
}
)
return trackList;
}
addRecommendationsToPlaylist(playlistName, playlistDescription, isPublic, tracks){
this.spotifyService.createPlaylist(playlistName, playlistDescription, isPublic, tracks).subscribe(
data => {
console.log(data);
})
}
publishPlaylistToSpotify(){
var topArtists = this.getTopArtists('artists', 'short_term', '5' ); //Get a user's recent top 5 artists.
var trackList = this.getRecommendations(topArtists); //Get a list of tracks based on top artists.
this.addRecommendationsToPlaylist('My Playlist', 'My Playlist Description', 'false', trackList); //Create a playlist and add tracks to it.
}
The way it stands, since the methods contain async requests, the publishPlaylistToSpotify() won't work as execution doesn't wait for topArtists and trackList to be fully fetched. In my publishPlaylistToSpotify(), how do I make sure that first topArtists is fully fetched, then trackList is fully fetched and then move on to creating the playlist?