Http request inside a loop Angular2 Typescript

1

I'm doing some exercises with Angular2 +, I do not have much experience with this version so I do not know how to achieve the idea that I have.

I want to invoke a service that returns the 10 most popular songs of the moment, when that answer arrives I would like to consume the Youtube API to obtain the data of each of the songs, that is, I want to make a cycle that invokes the API of youtube as many times as results bring the first service.

Here is an excerpt of what I have tried and that obviously does not work.

songs: Song[];
...
getItunesList(): Observable < Song[] > {
    let urlBase = "https://www.googleapis.com/youtube/v3/search?part= id,snippet&maxResults=1&q=";
    let youtubeKey = "&key=myKey";
    return this.http
        .get('http://www.mocky.io/v2/59ebfde03100001b02d24da4')
        .map(response => response.json().songsList as Song[])
        .mergeMap(songsList => {

            //Un ciclo para recorrer las diez canciones
            songsList.forEach(item => {

                //En el ciclo haría un llamado al servicio de youtube, pasando los parametros
                return this.http.get(urlBase + songsList[item].name + " " + songsList[item].artist + urlFin);


            })


        }).map(youTubeData => {
            //Ordenar resspuesta de youtube en el arreglo de objetos songs y finalmente devolver un solo arreglo con toda la información
            song.url = 'https://www.youtube.com/watch?v=' + youTubeData.items[0].id.videoId;
            song.thumbnail = youTubeData.items[0].snippet.thumbnails.default.url;

            return song;
        });
}

Please, I would like guidance on how to achieve the cycle of HTTP invocations within an answer, thanks!

    
asked by user3891850 05.11.2017 в 03:14
source

1 answer

0

Look at the definition of the forEach callback:

link

In particular the part that says:

  

Return value    undefined.

That is, when you do:

  

return this.http.get (...)

That returned value is not used by anyone.

What you could do then is to concatenate all the observables that result from your callback, and return that concatenation:

Example of the concat operator: link

const sourceOne = Rx.Observable.of(1,2,3);
const sourceTwo = Rx.Observable.of(4,5,6);
const example = sourceOne.concat(sourceTwo);
//salida: 1,2,3,4,5,6
const subscribe = example.subscribe(val => alert('Ejemplo concat:' + val));

In your code it would be something like this:

songsList => {
    var concatObs = null;
    //Un ciclo para recorrer las diez canciones
    songsList.forEach(item => {
        //En el ciclo haría un llamado al servicio de youtube, pasando los parametros
        var nuevoItem = this.http.get(urlBase + songsList[item].name + " " + songsList[item].artist + urlFin);

        if (concatObs) {
            concatObs = concatObs.concat(nuevoItem);
        } else {
            concatObs = nuevoItem;
        }
    });

    return concatObs;
});
    
answered by 06.11.2017 в 23:31