sickk sickk - 4 years ago 82
AngularJS Question

AngularJS: ng-repeat doesn't show always the data

I have got a strange problem: my search form starts three different request to my server but when angular has to show the data often the data doesn't appear. I'm sure that the data comes from the server cause I see them in FireBug. All the requests are sended...but I think that not all are processed by angularJS. Maybe I'm wrong about its use.

Here my code:

$scope.queryUser = {};
$scope.index = ['central', 'distributed', 'other'];
//$scope.index = ['distributed'];
$scope.results = {};
$scope.url = "/MyApp/search.do?index=" ;

$scope.search = function(query) {

$scope.queryUser= angular.copy(query);

// Create the http post request
// the data holds the keywords
// The request is a JSON request.
for( i in $scope.index ){
$http.get($scope.url + $scope.index[i] + "&query=" + $scope.queryUser.value).
success(function(data, status, headers, config) {
$scope.status = status;
$scope.results[$scope.index[i]+"Items"] = data;

console.log(i);
for(x in $scope.results.distributedItems){
console.log(x);
}
})
.
error(function(data, status) {
$scope.data = data || "Request failed";
$scope.status = status;
console.log("error: " + $scope.status);
});
}


indeed, the console.log prints the index only one time...it's strange for me. I think the three requests are overlapped.

Then the code of ng-repeat

<div id='aggregated_results_domain'>
<div id="results_distributed">
<table id="table_results_distributed" cellspacing="5" cellpadding="3" bgcolor="#eee">
<tr ng-repeat="(keyDistributed, valueDistributed) in results.distributedItems">
<td>{{keyDistributed}}</td>
</tr>
</table>
</div>
<div id="results_central">
<table id="table_results_central" cellspacing="5" cellpadding="3" bgcolor="#eee">
<tr ng-repeat="(keyCentral, valueCentral) in results.centralItems">
<td>{{keyCentral}}</td>
</tr>
</table>
</div>
<div id="results_other">
<table id="table_results_other" cellspacing="5" cellpadding="3" bgcolor="#eee">
<tr ng-repeat="(keyOther, valueOther) in results.otherItems">
<td>{{keyOther}}</td>
</tr>
</table>
</div>


Any suggestions?

Thanks in advance

Answer Source

Mixing loop variable scope with async calls is a classical mistake in JS. The scope of i variable is incorrect in the for-loop.

To fix the problem, use the .forEach function or create a function which captures i in its scope:

    $scope.index.forEach(function (i) {
        $http.get($scope.url + $scope.index[i] + "&query=" + $scope.queryUser.value).
        success(function(data, status, headers, config) {
            $scope.status = status;
            $scope.results[$scope.index[i]+"Items"] = data;

            console.log(i);
            for(x in $scope.results.distributedItems){
                console.log(x);
            }
        })
        .
        error(function(data, status) {
            $scope.data = data || "Request failed";
            $scope.status = status;   
            console.log("error: " + $scope.status);
        });
    });
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download