0

Given the following data on the server:

people.json:

{
  "Bill": "Bill the Man",
  "Jane": "Jane Doe",
  "Jack": "Jack the Ripper"
}

groups.json:

[
   ["Bill", "Jack"],
   ["Jane", "Jack"]
]

I import it in controllers.js:

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

websiteApp.controller('websiteCtrl', function ($scope, $http) {
  // import data
  $http.get('people.json').success(function (data) {
    $scope.people = data;
  });
  $http.get('groups.json').success(function (data) {
    $scope.groups = data;
  });

  // fill groups with people data
  $scope.groups.forEach(function (group, i) {
    group.forEach(function (person, j) {
      $scope.groups[i][j] = $scope.people[person];
    });
  });
});

And then I use this with the following template:

<ul>
  <li ng-repeat="group in groups">
    <ul><li ng-repeat="person in group">{{person}}</li></ul>
  </li>
</ul>

I expected to get a list of lists of names from people.json, but I get the first names as in groups.json. Some further investigation with console.log made it clear that the forEach loops are not executed. Further trials with local variables to store the data before assigning to the scope also did not succeed.

How should I approach this issue? What am I not understanding about how Angular works? (N.B.: I am new to Angular and Javascript frameworks in general.)

2
  • 1
    both of the $http.get calls are async. So, there will be no data yet when the forEach runs. Commented Feb 12, 2015 at 11:17
  • 1
    The foreach is being hit before the .success of each http call due to the async nature Commented Feb 12, 2015 at 11:18

2 Answers 2

2

Try something like this...

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

websiteApp.controller('websiteCtrl', function($scope, $http, $q) {
    // import data

    getPeopleAndGroups = function() {

        var people = $http.get('people.json');
        var groups = $http.get('groups.json');

        return $q.all([people, groups]);
    }


    getPeopleAndGroups().then(function(data) {
        var people = data[0].data;
        var groups = data[1].data;

        // fill groups with people data
        groups.forEach(function(group, i) {
            group.forEach(function(person, j) {
                $scope.groups[i][j] = $scope.people[person];
            });
        });
    })
});

Using the $q library, you can return a promise, so this should help you out - I cant validate it as I'm in work, but it should get you on track. Take a look at the Angular q Library

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

Comments

1

$http is asynchronous in nature, you need to call the foreach, when both ajax requests are completed. For example:

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

websiteApp.controller('websiteCtrl', function ($scope, $http) {
    // import data
    $http.get('people.json').success(function (data) {
        $scope.people = data;
        $http.get('groups.json').success(function (data) {
            $scope.groups = data;
            // fill groups with people data
            $scope.groups.forEach(function (group, i) {
                group.forEach(function (person, j) {
                    $scope.groups[i][j] = $scope.people[person];
                });
            });

        });
    });



});

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.