0

In my Angular 6 service, I have the following method to get the current user's first 50 playlists from the Spotify Web API:

getPlaylists(accessToken: string): Observable<Playlist[]> {
  const httpOptions = {
    headers: new HttpHeaders({
      'Authorization': `Bearer ${accessToken}`
    })
  };

  return this.httpClient.get<Playlist[]>('https://api.spotify.com/v1/me/playlists?limit=50', httpOptions)
    .pipe(map((response: any) => response.items));
}

This works well enough if the current user only has 50 playlists or fewer.

However, if a user has more than 50 playlists, the Spotify Web API limits the number of playlists in a single response to 50, and instead the response object contains a next property, which is the URI for the endpoint to request the next 50 playlists.

I would like to extend the getPlaylists function to get all of a user's playlists, i.e.: as long as the response object contains a valid next property, I'd like to keep sending GET requests to the URI it contains, and finally merge the resulting response.items arrays so that the function returns a single Observable<Playlist[]>.

How would I go about doing so?

Thanks!

EDIT: The Spotify Web API endpoint I'm using is https://developer.spotify.com/documentation/web-api/reference/playlists/get-a-list-of-current-users-playlists/

Joris
  • 309
  • 2
  • 12
  • I doubt it is the fastest way to do it, but you could do a recursion checking for the next object. Another way would be to forkjoin on two queries first, asking for offset 0 and offset 50 (cf. API), and check if the second query returns results. – Standaa - Remember Monica Jul 16 '18 at 10:34

1 Answers1

2

You could use .mergeMap() which helps you to flatten your high-order Observable into a single stream.

Simple Example of Hello World

//emit 'Hello'
const source = Rx.Observable.of('Hello');
//map to inner observable and flatten
const example = source.mergeMap(val => Rx.Observable.of(`${val} World!`));
//output: 'Hello World!'
const subscribe = example.subscribe(val => console.log(val));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.1.0/Rx.js"></script>

To have better understanding between .map() and .mergeMap()- check this question and answer

Keshan Nageswaran
  • 8,060
  • 3
  • 28
  • 45