daydreamer
daydreamer

Reputation: 91949

AngularJS: How can I populate data from server before rendering?

My HTML is

<div id="categories" ng-controller="AddTransactionCtrl">
    <tr ng-repeat="category in categories">
        <td><a href="{{category.name}}" target="_blank">{{category.name}}</a></td>
        <td>{{category.description}}</td>
    </tr>
</div>

I want to populate this list from Controller that fetches the data from server. My controller looks like

function AddTransactionCtrl($scope, $http) {
  $scope.transaction = {};
  $scope.transaction.categories = [];
  $http({
    method: 'GET',
    url: '/categories'
  }).success(function(data, status, headers, config) {
      console.log('/categories succeeded. - ' + data.length);
      $scope.transaction.categories = data;
    }).error(function(data, status, headers, config) {
      console.log('/categories failed.');
    });

  console.log($scope.transaction.categories.length);

  $scope.save = function() {
    console.log('will add transaction');
    console.log('name:' + $scope.transaction.name);
    console.log('date:' + $scope.transaction.date);
    console.log('desc:' + $scope.transaction.desc);
  }
}

When I refresh my page and see on Chrome console, I see

0
/categories succeeded. - 151

Question
a.) How can I make sure that the categories are populated by HTTP before anything related to rendering on page or console is printed out

Upvotes: 2

Views: 2410

Answers (1)

Ayush
Ayush

Reputation: 42450

You're correct that the call is asynchronous. Whatever needs to be done after categories has been populated should go within the success callback function of the $http call.

Also, your ng-repeat directive is wrong. It should be

<tr ng-repeat="category in transaction.categories">

With your code setup like this, the tr elements will now only show up after transaction.categories has been populated by the $http call.

Also, you say

Which means that $scope.transaction.categories is not assigned

This is not correct. It just hasn't been assigned yet. Your final $http call should look like this:

function AddTransactionCtrl($scope, $http) {
  $scope.transaction = {};
  $scope.transaction.categories = [];
  $http({
    method: 'GET',
    url: '/categories'
  }).success(function(data, status, headers, config) {
      console.log('/categories succeeded. - ' + data.length);
      $scope.transaction.categories = data;

      // this will show you the count that you expect
      console.log($scope.transaction.categories.length);
    }).error(function(data, status, headers, config) {
      console.log('/categories failed.');
    });

  // this will always print 0 to console
  // since categories has not been assigned yet
  console.log($scope.transaction.categories.length);

  // other methods
}

Upvotes: 3

Related Questions