0

I am new to angular 1, and I have problem with my code:

var app = angular.module("Football", []);

app.factory("competitions", ['$http', function($http) {
  return $http.get("json/competitions.json")
  .success(function(response) {

    var data = {
      response: response,
      teams: []
    };

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

      $http.get("json/teams.json")
      .success(function(response2) {
        data.teams.push(response2);
        return data
      })
      .error(function(err) {
        return err;
      });
    }

  })
  .error(function(err) {
    return err;
  });
}]);


app.controller('MainController', ['$scope', "competitions", function($scope, competitions) {
  competitions.success(function(data) {
    $scope.competitions = data;
  });
}]);

I want to pass data from competitions factory to $scope.competitions in MainController. After last iteration of for loop data variable should be passed to the controller. I know this code is wrong, beacuse it passes only response to controller, but I don't know how to fix it. Could someone help me?

3 Answers 3

3

You're doing a few things wrong here.

  1. The .success() and .error() functions are not used anymore. Use .then() instead.

  2. The .success() function has four parameters. The first one is the data that is returned, so response is the actual data, not the whole response. If you use .then(), then you'll get the response back, which you can extract data out of.

  3. Use the $q library to return your own promise rather than returning data from a factory. You can extract that data in your controller, as you should.

  4. Don't run a loop off of response directly, since you never know if it'll be an array or not. If it's an actual response, it'll be a wrapper around the actual data.

  5. Where's the returned data and err from the teams.json promise going? I'd guess that that part's empty.

  6. Promises take eons to resolve compared to code, so I'd advise you to not call the teams.json from the factory, but from the controller. That is, substitute a dummy inside an ng-repeat in your scope, then when this data comes back, put the actual data in place of the dummy.

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

1 Comment

Any more doubts, feel free to ask.
0

Try this one

    var app = angular.module("Football", []);

app.factory("competitions", ['$http', '$q', function ($http, $q) {
  function getCompetitions(){
    return $http.get('json/competitions.json');
  }
  return {
    get: function(){
      var mainTask = $q.defer();
      getCompetitions().then(function(response){
        var compData = {
          competitions: response.data,
          teams:[]
        }
        var tasks = [];
        for(var i=0;i<compData.competitions.length;i++){
          tasks.push($http.get("json/teams.json"));
        }
        $q.all(tasks).then(function(responses){
          for(var j = 0;j<responses.length;j++){
            compData.teams.push(responses[i]);
          }
          mainTask.resolve(compData);
        }).catch(function(error){
          mainTask.reject(error);
        })
      }).catch(function(error){
        mainTask.reject(error);
      }) 
      return mainTask.promise;
    }
  }
}]);


app.controller('MainController', ['$scope', "competitions", function ($scope, competitions) {
  competitions.get().then(function(data){
    $scope.competitions = data;
  }).catch(function(error){
    //catch error here
  })
}]);

3 Comments

Thank you for help, but it didn't help, the result is still the same - the only data I receive is only that from competitions.json. I presume, that after first return, the code doesn't care what's inside success function (it's async request after all), so maybe other approach should be considered? Or it's not possible to do?
@Michal, see my updated answer. If it will not help please create plunkr or jsfiddle and I will edit it.
I combined your previous answer and @cst1992 and now it works, thanks a lot!
0

I think the solution for your case is to have a first request to the competitions then group all of the requests and resolve then with a $q.all. Check the following jsbin: http://jsbin.com/korenodota/1/edit?html,js,console

var app = angular.module("AngularApp", ['test']);

angular.module('test', [])
  .controller('TestController', ['$scope', 'CompetitionsService', function ($scope, CompetitionsService) {
    $scope.competitions = [];

    CompetitionsService.getCompetititons().then(function (response) {
      $scope.competitions = response;
      console.log($scope.competitions);
    });
  }])
.service('CompetitionsService', ['$q', function($q) {
    var getCompetititons = function() {

       // Replace with your competition's http request
       return $q(function (resolve) {
         return resolve([{
           id: 1,
           competition: 'DUMMY-1'
         }, {
           id: 2,
           competition: 'DUMMY-2'
         }])
       }).then(function (competitions) {
         var promises = competitions.map(function (competition) {

           // Replace with your team's http request
           return $q(function (resolve) {
             var teamBaseName = competition.id;
             competition.teams = [teamBaseName + '1', teamBaseName + '2'];
             return resolve(competition)
           });
         });

         return $q.all(promises);
       });
    };

    return {
      getCompetititons: getCompetititons
    };
}]);

PS: be aware that I didn't had the exact http requests and I just replaced with normal promises returning dummy 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.