sickk
sickk

Reputation: 55

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

Upvotes: 2

Views: 918

Answers (2)

tjespe
tjespe

Reputation: 702

I realize that I am three years late, but for others having the problem I want to share what I usually do to fix this. It's really simple, I just change for (i=0;… to for (let i=0;…. This magically fixes everything by just adding one word.

It works because the let keyword scopes the variable to the block instead of the function.

Upvotes: 0

musically_ut
musically_ut

Reputation: 34288

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);
        });
    });

Upvotes: 2

Related Questions