0

I am using Spotify's API's search functionality to iterate through an array of SongSearchParams defined as:

export class SongSearchParams {
    public title: string;
    public artist: string;

    constructor(title: string, artist: string){
        this.title = title;
        this.artist = artist;
    }
}

My HTTP request looks like:

  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})
      .map(res => res.json());
  }

And in one of my component's typescript file I have access to the array of SongSearchParams that I want to individually pass into this searchTrack function when a certain button is clicked and save the album-image, trackname, and artist of a song.

onClick(){
  for(let searchQuery of this.songService.songSearches){ 
    this.spotifyserv.searchTrack(searchQuery)
      .subscribe(res => {
        this.searchedSong.artist = res.tracks.items[0].artists[0].name;
        this.searchedSong.title = res.tracks.items[0].name;
        this.searchedSong.imagePath = res.tracks.items[0].album.images[0].url;
        console.log(this.searchedSong);
        this.songService.addSong(this.searchedSong);
      })
  }
}

When I run this code, the console logs the correct song for each iteration but for some reason only the last song in my songSearches array gets physically added for the length of songSearches times.

Googling for answers to this issue, it seems that I need to use Promises called right after the other using the then() functionality so I tried implementing (for the searchTrack function):

This makes me think that it is an issue with my addSong function

addSong(song: Song){
    this.songs.push(song);
    this.songsChanged.next(this.songs.slice());
}

Though I don't really know what could be wrong with it so my second hunch is that I should be using promises called right after the other (which I have tried) but have failed to implement.

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

2 Answers2

0

I think take a look at forkjoin

so something along the lines of:

let obsArray = [];

for(let searchQuery of this.songService.songSearches) {
    obsArray.push(this.spotifyserv.searchTrack(searchQuery));
}

Observable.forkJoin(obsArray)
    .subscribe(results => {
        // results[0]
        // results[1]
        // ...
        // results(n)
    });
thelim3y
  • 21
  • 3
0

I discovered the solution to my problem though I do not know why it fixes it (I only have an assumption).

In the class where I created the onClick() method, I had a private member of type Song called songSearched which I was trying to overwrite for each song being added to the list. I instead rewrote the function to look like:

onClick(){
  for(let searchQuery of this.songService.songSearches){ 
    this.spotifyserv.searchTrack(searchQuery, 
          response => {
            let res = response.json();
            console.log(res.tracks.items[0].album.images[0].url);
            console.log(res.tracks.items[0].name);
            console.log(res.tracks.items[0].artists[0].name);
            let searched_song = {artist : null, title : null, imagePath : 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;
            console.log(searched_song);
            //song_queue.push(searched_song);
            this.songService.addSong(searched_song);
          }
    )
  }
}

Here I instead create a new searched_song to be appended to the list inside the function itself that way for each request, there exists a searched_Song. I think before what was happening was that I was overwriting the same searchedSong and by the time it got to the addSong(searchedSong) the final song had already been searched with Spotify's API and had already overwritten the previous searches so that one song kept getting added.

Though this still wouldn't explain why the console log works in the previous line in my original attempt.

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