Eric Mitjans
Eric Mitjans

Reputation: 2169

Logic problems with AngularJS and multiple $http queries

I have an app that will make 2 $http queries to an external API and get 2 different JSON responses. These responses will populate a ng-repeat, headers, etc. My problem is that I want to include a 3rd query, dependent on the first two.

Like so:

I get artist JSON and release JSON, and I use artist.name and release.title to populate the URL of the third $http query.

So far I've managed to get the two first queries, and once the results they are displaying in the ng-repeat, with ng-click I launch the 3rd query and populate an img ng-src.

Buuut, my problem is that I want the img ng-src to be populated automatically without ng-click, so the function that triggers the 3rd query has to get launched right after the 2 first queries. And also, in my working version right now, the img that I fetch with ng-click, will populate all items in ng-repeat. Meaning that every item should get their own image, and right now they don't.

I've created a working Plunker, if you search for a music artist and click on a result and then on an album, you'll see what I mean.

Basically, I think I'm missing a piece of logic that will put everything together and in proper trigger order.

Any thoughts?

My JS:

angular.module('myApp', ['ngResource'])

  function Ctrl($scope, $http) {
    var search = function(name) {
      if (name) {
        $http.get('http://api.discogs.com/database/search?type=artist&q='+ name +'&page=1&per_page=5').
          success(function(data3) {
            $scope.clicked = false;
            $scope.results = data3.results;
          });
      }
      $scope.reset = function () {
        $scope.sliding = false;
        $scope.name = undefined;
      }
    }
    $scope.$watch('name', search, true);

    $scope.getDetails = function (id) {
      $http.get('http://api.discogs.com/artists/' + id).
        success(function(data) {
            $scope.artist = data;
        });
      $http.get('http://api.discogs.com/artists/' + id + '/releases?page=1&per_page=100').
        success(function(data2) {
            $scope.releases = data2.releases;
        });
      $scope.clicked = true;
      $scope.sliding = true;
      $scope.getImages = function (title, name) {
        $http.get('http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=e8aefa857fc74255570c1ee62b01cdba&artist=' + name + '&album='+ title +'&format=json').
          success(function(data4) {
              $scope.images = data4;
          });
      }
    }


  };

My directive:

angular.module('myApp', ['ngResource'])

 .directive('artistData', function() {

      return{
          restrict: 'E',
          template: '<div class="col-md-8 col-md-offset-2"> \
                     <h1 ng-show="artist.name" class="artist-name">{{artist.name}}</h1>  \
                     <div class="header-border" ng-show="artist.name"></div> \
                     <input ng-show="artist.name" class="form-control" ng-model="album" /> \
                      <div class="col-md-3" ng-click="getImages(release.title, artist.name)" ng-repeat="release in releases | filter:album | filter:{ role: \'main\' }"><div class="release">{{release.title}}<img class="img-responsive" ng-src="{{images.album.image[2][\'#text\']}}" /></div></div> \
                     </div>',
          replace: true
      };
    })  

And my HTML:

<div class="container">
  <div class="row" ng-controller="Ctrl">
    <div class="col-md-8 col-md-offset-2">
      <div class="intro">

        <div class="intro-text" ng-class="{'slide':sliding}">
          <h1>Howdy stranger!</h1>
          <h3>Use the form below to search for an artist and start building your record collection!</h3>
        </div>
        <input type="text" ng-model="name" class="form-control input-lg" ng-class="{'slide':sliding}" ng-focus="reset()" placeholder="Artist name"/>
      </div>
      <ul ng-hide="clicked" class="search-results">
        <li ng-repeat="result in results" ng-click="getDetails(result.id)">{{result.title}}</li>
      </ul>
    </div>
    <artist-data></artist-data>
  </div>  
</div>

Upvotes: 1

Views: 415

Answers (1)

Maxim Shoustin
Maxim Shoustin

Reputation: 77904

I would use "Chaining Promises" in this case.

In basic words you call new async task on response of previous.

enter image description here

You can read this POST that might help you

Upvotes: 2

Related Questions