Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angularjs ng-repeat doesn't update when the model changes

I Have this code in my project. I try to add data from database using $http, but ng-repeat doesn't update de table, only shows a blank row.

When I check the scope, data is already there. I've read many answers but they does not seem to be related to my problem.

<div ng-controller="TweetsController">  
<table class="table table-striped table-bordered table-hover" width="100%">
    <thead>
        <tr>
            <th class="col-md-5"><i class="fa fa-fw fa-twitter text-muted hidden-md hidden-sm hidden-xs"></i> Texto</th>
            <th class="col-md-1 text-center"> Lista</th>
            <th class="col-md-1 text-center"> Cuenta</th>
            <th class="col-md-1 text-center"> Red</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="tuit in filtrado">
            <td>{{tuit.texto}}</td>
            <td class="text-center">{{tuit.lista.nombre}}</td>
            <td class="text-center">{{tuit.lista.cuenta.nombre}}</td>
            <td class="text-center">{{tuit.lista.cuenta.red.tipo}}</td>
        </tr>
    </tbody>            
</table>
<div>
    <pagination total-items="ufilter.length" itemsPerPage="itemsPerPage" ng-model="currentPage"></pagination>
</div>
</div>

Controller:

.controller('TweetsController', ['$scope','$http','filterFilter', function($scope,$http,filterFilter) {
    $scope.currentPage = 1;
    $scope.itemsPerPage = 10;
    $scope.filtrado = [];

    $scope.setPage = function (pageNo) {
        $scope.currentPage = pageNo;
    };

    // retrieve tweets
    $http.get('admin/twitter').success(function(tweets) {
        $scope.tweets = tweets;
    });

    $scope.saveTweet = function(isValid) {
        if(isValid) {
             var tuit = {
                texto: $scope.texto,
                lista_id: $scope.lista
            };

            $http.post('admin/twitter', tuit).success(function(t) {
                $scope.tweets.push(t);
            });
        }
    };

    $scope.filtrar = function(filtro) {
        if($scope.tweets != undefined) {
            $scope.ufilter = filterFilter(filtro, $scope.buscar);

            var inicio = ($scope.currentPage - 1) * $scope.itemsPerPage;
            var fin = inicio + $scope.itemsPerPage;

            $scope.filtrado = $scope.ufilter.slice(inicio, fin);
        }
    };

    $scope.$watch('tweets', function() {
        $scope.filtrar($scope.tweets);
    });

    $scope.$watch('currentPage', function() {
        $scope.filtrar($scope.tweets);
    });

    $scope.$watch('buscar', function() {
        $scope.filtrar($scope.tweets);
        $scope.setPage(1);
    });     

}])

EDIT:

I Solved it!

The problem is the way how the retrieve data is wrapped

$scope.tweets.push(t[0])
like image 402
Charger513 Avatar asked Aug 28 '14 21:08

Charger513


2 Answers

The problem is the way how the retrieve data is wrapped

instead of this:

$http.post('admin/twitter', tuit).success(function(t) {
            $scope.tweets.push(t);
        });

this:

$http.post('admin/twitter', tuit).success(function(t) {
            $scope.tweets.push(t[0]);
        });
like image 40
Charger513 Avatar answered Nov 15 '22 06:11

Charger513


You need to apply to the scope

 $http.get('admin/twitter').success(function(tweets) {
        $scope.tweets = tweets;
        $scope.$apply()
});

This is a great blog post that explains it:

http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

The reason why your ng-repeat is not updating after the $http request is due to the $http is async and your javascript turn for the controller has finished before the response is back from your $http request. So you must notify the scope that things have changed and push it to the scope.

like image 190
Mohamed El Mahallawy Avatar answered Nov 15 '22 07:11

Mohamed El Mahallawy