0

I am using Spotify's Web Api.

I have an array of songSearches. And for each songSearch within songSearches, a request is made to search for these songs and add it to an array of Songs that I have which hold the track's spotify ID. I need all of these IDs at once so I can execute one POST request to add all of these tracks to a playlist. Therefore, all of the search requests must be completed before the POST request is made.

All of this needs to happen at the click of a button.

Code executed when button is clicked:

onSubmit(){
  while (this.songsService.songSearches.length){
    this.spotifyserv.searchTrack(this.songsService.songSearches[0]);
    this.songsService.songSearches.shift();
  }
  this.spotifyserv.add_tracks_to_playlist(); //Needs to wait until all requests ^ have been completed
}

Search Track function:

searchTrack(searchParams: SongSearchParams, type='track'){
  var headers = new Headers({'Authorization': 'Bearer ' + this.hash_params.access_token});
  this.user_url = "https://api.spotify.com/v1/search?query="+searchParams.artist+' '+searchParams.title+"&offset=0&limit=1&type="+type+"&market=US";
  return this.http.get(this.user_url, {headers : headers})
    .subscribe(
      response => {
              var res = response.json();
              var searched_song = {artist : null, title : null, imagePath : null, spotifyID : null}
              searched_song.artist = res.tracks.items[0].artists[0].name;
              searched_song.title = res.tracks.items[0].name;
              searched_song.imagePath = res.tracks.items[0].album.images[0].url;
              searched_song.spotifyID = res.tracks.items[0].id;
              this.songsService.addSong(searched_song);
      }
    );
}

Add Tracks to Playlist function

add_tracks_to_playlist(){
  var headers = new Headers({'Authorization': 'Bearer ' + this.hash_params.access_token});
  headers.append('Accept', 'application/json');
  this.user_url = "https://api.spotify.com/v1/users/" + this.user_id + "/playlists/" + this.playlist_id + "/tracks"; 
  let songs: Song[] = this.songsService.getSongs(); //playlist_id is hardcoded rn. needs to be added dynamically
  let songIDs : String [] = [];
  for (var i = 0; i < songs.length; i++){
    songIDs.push("spotify:track:" + songs[i].spotifyID);
  }
  let body = {"uris": songIDs};
  this.http
      .post(this.user_url, JSON.stringify(body), {headers : headers})
      .toPromise()
      .then(response => console.log(response))
      .catch(this.handleError);
}

I understand that I probably want to be using Promise.all() somewhere but I am not sure how/where to use it

Luca Guarro
  • 1,085
  • 1
  • 11
  • 25

1 Answers1

1

As you mention, Promise.all() could help you if searchTrack() returns a Promise. So something like this:

searchTrack(searchParams: SongSearchParams, type='track') {
  // ...
  return this.http.get(this.user_url, {headers : headers})
    .toPromise()
    .then(response => {
       // Code from your subscribe
    });
}

and change the onSubmit

onSubmit(){
  const searchPromises: Promise<void>[] = [];
  while (this.songsService.songSearches.length){
    searchPromises.push(this.spotifyserv.searchTrack(this.songsService.songSearches[0]));
    this.songsService.songSearches.shift();
  }
  //Needs to wait until all requests ^ have been completed
  Promise.all(searchPromises)
    .then(() => this.spotifyserv.add_tracks_to_playlist());
}
Ján Halaša
  • 8,167
  • 1
  • 36
  • 36
  • Works like a charm and I think I understand promises a little better now. Thanks. – Luca Guarro Apr 14 '17 at 06:41
  • I'm glad to hear that. As you surely noticed, the trick was in `Promise.then()` returning a `Promise`. If you return some value from a `Promise.then()` callback, the returned `Promise` with hold the value as its result. Then you can get all the results as an array in `Promise.all(results => { ... })`. – Ján Halaša Apr 14 '17 at 06:49
  • That makes sense. Thank you for the clarification. So essentially Promise.all(searchPromises) .then callback only executes once all the searchPromises return true affirming that all requests were successful? – Luca Guarro Apr 14 '17 at 17:29
  • Yes, that's how it is :-) – Ján Halaša Apr 15 '17 at 06:53