1

New to angular. I am trying to call multiple $http get calls and the second call depending on the result and parsed JSON of the first one as follows:

1) Do an $http get request to get a JSON with an array of elements like ["album 1", "album2"]

2) Loop over each item in the array and do a different $http get request to get the track details for that album.

Here is the controller code for the same (incomplete) where I want to achieve this:

    var vm = this;
    vm.albums = init;
    vm.albums.tracks = albumTracks;
    vm.newFunction = newFunction;

    return init();

    return albumTracks ();

    function init(){

        $http.get('http://localhost:8080/api/albums').then(function(responseData){
            // Parse the json data here and display it in the UI
            vm.albums = responseData;
            $log.debug(angular.toJson(responseData, true));

        // For every album, do another get call in the function albumTracks
            for(var i=0; i<vm.albums.length; i++){
                vm.albums.tracks = [];
                vm.albums.tracks.push(albumTracks(vm.albums[i]));
                console.log(vm.albums.tracks);  // This prints on the console as [undefined]
            }

            console.log(vm.albums.tracks);
            return vm.albums;
        })
    }

    function albumTracks(album){
        $http.get('http://localhost:8080/api/albums/'+album).success(function(trackResponse){
            //parse each album and get the track list
            vm.albums.tracks = trackResponse;
            return vm.albums.tracks;
        })
    }

Here is how each JSON response looks like:

//http://localhost:8080/api/albums/:
 [
  "the-revenant-original-motion-picture-soundtrack",
  "twilight-of-the-ghosts"
 ]

//http://localhost:8080/api/albums/twilight-of-the-ghosts:
[
{
"fileName": "twilight-of-the-ghosts-twilight-of-the-ghosts-01-pinned-to-the-mattress.flac",
"title": "Pinned to the Mattress",
"artists": "Twilight of the Ghosts",
"album": "Twilight of the Ghosts",
"sequenceNumber": 1,
"trackLength": 274
},
 {
"fileName": "twilight-of-the-ghosts-twilight-of-the-ghosts-02-sinking-slowly-slowly-sinking.flac",
"title": "Sinking Slowly Slowly Sinking",
"artists": "Twilight of the Ghosts",
"album": "Twilight of the Ghosts",
"sequenceNumber": 2,
"trackLength": 270
}
and so on

2 Answers 2

1

Currently you will overwrite tracks with each tracksResponse. You may want to do:

vm.album.tracks = vm.album.tracks.concat(trackResponse);

Instead, you want to associate the albums and tracks, so use an array of objects for the albums instead of an array of strings:

vm.albums = responseData.map(album => ({name: album, tracks: []}));

Then, you will pass in the album object which you can update after the tracks request:

album.tracks = trackResponse;

The console.logs will not work where you have them because $http is asynchronous.

let a = "a";
$http.get(() => a = "b");
console.log(a); // logs "a" even though it was written after `a = "b"`

This means that if you are depending on the response of the $http request for anything you have to do that work in the callback of the request. You probably don't need to do that in this case, though, since updating the vm should update your templates automatically because of how Angular works.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks. Are you also suggesting that I remove the loop I have ? I am a bit lost there. Like should I use an http.get(....).then(function() another http get()) etc ?
@noobcoder no, the loop is fine. You can do those http requests simultaneously so the asynchronicity is beneficial here
Thanks again. I dont think I understand the syntax responseData.map(album => ({name: album, tracks: []})); The => is unclear to me. Is that how we create a map object in angular ?
@noobcoder this is an arrow function -- you may be using a browser that does not support them. Just use the regular function () {} syntax instead.
0

As per my Knowledge You may need to angular-loop instead of 'for'loop where you can attach trackers with out Some more coding and chaos.

vm.albumsWithTrackers = []; // New Variable Defining needed.

//http://localhost:8080/api/albums/: // it is fine Json but with some define attributes it looks good 
                 [
                  "the-revenant-original-motion-picture-soundtrack",
                  "twilight-of-the-ghosts"
                 ]

      //  Albums With attributes Defined :- 

        [
          "id":"the-revenant-original-motion-picture-soundtrack",
          "id":"twilight-of-the-ghosts"
         ]

        angular.forEach(vm.albums, function (album, key) {
                    album.tracks.push(albumTracks(album));  // attaching only trackers to current album on loop 
                    vm.albumsWithTrackers.push(album); // pushing Album to new defined variable
                    console.log(album.tracks);  
                    });
                });
               console.log(vm.albumsWithTrackers);//album with attached trackers.
            return vm.albumsWithTrackers;

    function albumTracks(album){
            $http.get('http://localhost:8080/api/albums/'+album.id).success(function(trackResponse){
                 return trackResponse; //send trackers response directly
            })
        }

I hope this approach Will help to sort Your issue :-) Thanks.

3 Comments

I tried the angular forEach but the problem is, it doesn't read the array in order. For instance, if my albums array is [album1, album2], for some unknown reason to me, it reads album 2 first and then album1
it is not looping because there is no object in Loop it loops when [{obj1},{obj2}]. you have a confirmed object model with response as array ? I Mean you dont wanna change the model and response and you are expecting Out put with this response ? But Angular and Json relationship is all runs on Objects in arrays
Do you wanna change the resonse array in to array of Objects .. actually that is a good practice you will find it Down the Road .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.