0

I'm trying to make couple of HTTP requests, one inside another, and I'm having a trouble restructuring my JSON object.

I have a factory function, first of all i'm trying to get all the teams, each team has an Id, and then i'm getting all the news for each team with the id related, and putting that news in the first JSON object.

but this is not working !

.factory('teamsFactory', function ($http,CacheFactory,LocaleManager,$q) 
{

   teams.Getteams= function() 
    {
        var zis=this;
    var promise=$http({method:"GET",url:"http://www.myserver/teams"});
    promise.then(function(response){

    for (var i=0;i<response.data.length;i++) {

     zis.getTeamsNews(response.data[i].idTeam).then(function(newsresponse){

     response.data[i].news=newsresponse.data;

     });
    }


    },alert('error'));
    return promise;         
    }


    teams.getTeamsNews= function(idTeam) 
    {
    var promise=$http({method:"GET",url:"http://www.myserver.com/news?team="+idTeam});
    promise.then(null,alert('error'));
    return promise;         
    }

});
3
  • possible duplicate of AngularJS nesting $http calls Commented Jul 29, 2015 at 8:45
  • @DTing no it's similar, me i'm having an HTTP request that depends on another, I can't get both of them in the same time ! Commented Jul 29, 2015 at 8:51
  • @DTing Could you please read carefully my post for better understanding Commented Jul 29, 2015 at 8:52

3 Answers 3

1

I think it's better to push all the $http promises into an array and then use $q.all() to group them together rather than calling them each individually in a loop. Try this:

Note I had to move some of your functions around and create dummy data etc. so you will have to alter it slightly to fit your app.

DEMO

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope, teamsFactory) {
  $scope.name = 'World';

  teamsFactory.Getteams()
  .then(function(data){
    $scope.teamsData = data;
  });

});

app.factory('teamsFactory', function ($http, $q){

  var teams = {};

  teams.getFavoriteTeamsNews = function(teamId){
    return $http
      .get('news.json')
      .then(function(response){
        console.log('gtTeamNews response', response);
        return response.data[teamId];
      })
  }

  teams.Getteams = function(){

    var zis = this,

        httpConfig = {
          method  : "GET", 
          url     : "teams.json"
        };

    return $http(httpConfig)
      .then(function(response){

        var teamId, promise,

            requests = [];

        for(var i = 0; i <response.data.length; i++){

          teamId  = response.data[i].idTeam;
          promise = teams.getFavoriteTeamsNews(teamId);

          requests.push(promise);

        }

        return $q
          .all(requests)
          .then(function(responses){

            angular.forEach(responses, function(newsresponse, index){
              response.data[index].news = newsresponse;
            });

            return response.data;

          });


      })
      .catch(function(error){
        console.log('error', error);
      });   

  }


  return teams;


  // teams.TeamsNews= function(idTeam){
  //   return $http({method:"GET",url:"http://www.myserver.com/news?team="+idTeam})
  //           .catch(function(){
  //             alert('error')
  //           });

  // }

});

update

You could also re-factor the above to take advantage of promise chaining which makes it much cleaner in my opinion. This should give the same output but is more 'flat', i.e. has less indentation/callback hell:

DEMO2

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope, teamsFactory) {
  $scope.name = 'World';

  teamsFactory.Getteams()
  .then(function(data){
    $scope.teamsData = data;
  });

});

app.factory('teamsFactory', function ($http, $q){

  var responseData,

      teams = {};

  teams.getFavoriteTeamsNews = function(teamId){
    return $http
      .get('news.json')
      .then(function(response){
        console.log('gtTeamNews response', response);
        return response.data[teamId];
      })
  }

  teams.Getteams = function(){

    var zis = this,

        httpConfig = {
          method  : "GET", 
          url     : "teams.json"
        };

    return $http(httpConfig)
      .then(function(response){

        var teamId, promise,

            requests = [];

        responseData = response.data;

        for(var i = 0; i < responseData.length; i++){

          teamId  = responseData[i].idTeam;
          promise = teams.getFavoriteTeamsNews(teamId);

          requests.push(promise);

        }

        return $q.all(requests);

      })
      .then(function(responses){

        angular.forEach(responses, function(newsresponse, index){
              responseData[index].news = newsresponse;
        });

        return responseData;
      })
      .catch(function(error){
        console.log('error', error);
      });   

  }


  return teams;

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

Comments

1

eventually something like that .. this is raw solution .. could be enhanced with caching ...

var module = angular.module('myapp', []);

module.factory('teamsFactory', function ($http,CacheFactory,LocaleManager,$q)
{

    function ExtractTeamFromData(data){
        // TODO
        console.log("TODO: Exctract teams from data ...");
    }
    function FindTeamById(teams, tgeamId){
        // TODO
        console.log("TODO: Find team by id ...");
    }
    function ExtractNewsFromData(data){
        // TODO
        console.log("TODO: Exctract news from data ...");
    }


    var GetTeams= function()
    {
        var zis=this;
        var promise = $http({method:"GET",url:"http://www.myserver/teams"});
        var successCallback = function(data, status, headers, config) {
            var teams = ExtractTeamFromData(data);
            return teams;
        };

        var errorCallback = function(reason, status, headers, config) {
            console.error("Some error occured: " + reason);
            return {
                'errorMessage': reason
            };
        }
        promise.then(successCallback,errorCallback);
        return promise;
    }



    var GetTeam = function(idTeam)
    {
        var promise = GetTeams();
        var successTeamsCallback = function(teams, status, headers, config) {
            return FindTeamById(teams, tgeamId);
        };
        var errorTeamsCallback = function(reason, status, headers, config) {
            console.error("Some error occured: " + reason);
            return {
                'errorMessage': reason
            };
        }
        promise.then(successTeamsCallback,errorTeamsCallback);
        return promise;
    }


    var GetTeamsNews = function(idTeam){
        var promise = GetTeam(idTeam);
        var successTeamCallback = function(team, status, headers, config) {
            var newsPromise = $http({method:"GET",url:"http://www.myserver.com/news?team="+idTeam});
            var successNewsCallback = function(data, status, headers, config) {
                var news = ExtractNewsFromData(data);
                return news;
            };
            var errorNewsCallback = function(reason, status, headers, config) {
                console.error("Some error occured: " + reason);
                return {
                    'errorMessage': reason
                };
            }
            newsPromise.then(successNewsCallback,errorNewsCallback);
            return newsPromise;
        };
        var errorTeamCallback = function(reason, status, headers, config) {
            console.error("Some error occured: " + reason);
            return {
                'errorMessage': reason
            };
        }
        promise.then(successTeamCallback,errorTeamCallback);
        return promise;
    }

    return {
        GetTeams: GetTeams,
        GetTeam: GetTeam,
        GetTeamsNews: GetTeamsNews
    };

});

Comments

0

You need to create a promise of your own, and resolve it when done, this way :

return $q(function(resolve, reject) {

    $http({method:"GET",url:"http://www.myserver/teams"}).then(function(response){
        var promises = [];
        for (var i=0;i<response.data.length;i++) {
            promises.push(zis.getFavoriteTeamsNews(response.data[i].idTeam)).then(function(newsresponse){
                response.data[i].news=newsresponse.data;
            });
        }
        $q.all(promises).then(function(){
            resolve(response);
        });
    });

    for (var i=0;i<response.data.length;i++) {

     zis.getFavoriteTeamsNews(response.data[i].idTeam).then(function(newsresponse){

     response.data[i].news=newsresponse.data;

     })
});

Comments

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.