user2965954
user2965954

Reputation: 3

AngularJS View Not Being Updated

I'm an angular noob. This is my first 'real' angular app. It simply displays transactions or statistics for a user specified date. The data comes from a RESTful service. I'm running into issues getting my view to update when data returned from this service changes. My application displays a date input field... where the user can specify the date for reports i've generated. The date is used in both of my controllers... so i've created a service to make this available. The app initializes and displays the statistics report for today This works fine. When the user changes the date field, the heading on the page updates ('Statistics for {{drDate}}'). I have a watch on the fileName which is host/service/{{drDate}}. This causes the controller to re-retrieve the specified data. This works fine. However, even though the data has been modified... the UI does NOT update I have an ng-repeat displaying my data in table. This does NOT update the view. I've played with $watch, $apply and a bunch of other things... but have not been able to get this to update. The fact that this has been so difficult leads me to believe that i'm just approaching this wrong? If i switch between views (statistics & transactions)... each template displays correctly when it initially renders... but not on user provided input. Below is the code for my controllers and templates. Statistics only to conserve space. Any help is greatly appreciated!!

--app.js--

'use strict';
// Declare app level module which depends on filters, and services
var statsApp = angular.module('statsApp', [
    'ngRoute',
    'statsAppControllers'
]);

statsApp.config(['$routeProvider',
    function ($routeProvider) {
        $routeProvider.
            when('/statistics', {
                templateUrl: 'partials/statistics.html',
                controller: 'StatisticsCtrl'
            }).
            when('/transactions', {
                templateUrl: 'partials/transactions.html',
                controller: 'TransactionsCtrl'
            }).
            otherwise({
                redirectTo: '/statistics'
            });
    }]);

--controllers.js--

'use strict';

var statsAppControllers = angular.module('statsAppControllers', []).service(
        'SharedProperties', function() {
            return {
                drDate : {
                    current : getFormattedDate()
                }
            };
        });

statsAppControllers.controller('StatisticsCtrl', function($scope, $http,
        SharedProperties) {
    $scope.message = 'Inside Statistics Controller';
    $scope.drDate = SharedProperties.drDate;
    var fileName = 'http://tomcatHost : 8080/counts/'
            + $scope.drDate.current;
    $scope.fileName = fileName;

    $scope.$watch('fileName', function() {
        alert('inside scope.watch');
        getStatistics($scope, $http, fileName);
    });

    getStatistics($scope, $http, fileName);

    $scope.dateChanged = function() {
        alert('dateChanged:' + $scope.$$phase);
        getStatistics($scope, $http, fileName);
    };
});

function getStatistics($scope, $http, fileName) {
    var fileName = 'http://tomcatHost : 8080/counts/'
            + $scope.drDate.current;

     alert('getStatistics() ' + fileName);

    $http.get(fileName).success(function(data, status, headers, config) {
        $scope.statistics = {};
        $scope.statistics.items = data;

    }).error(function(data, status, headers, config) {
        alert('http.get() error retrieving ' + fileName);
    });
}

statsAppControllers.controller('TransactionsCtrl', function($scope, $http,
        SharedProperties) {
    $scope.message = 'Inside Transactions Controller';
    $scope.drDate = SharedProperties.drDate;
    var fileName = 'http://tomcatHost : 8080/transactions/'
            + $scope.drDate.current;
    $http.get(fileName).success(function(data, status, headers, config) {
        $scope.transactions = {};
        $scope.transactions.items = data;
    }).error(function(data, status, headers, config) {
        alert('http.get() error retrieving ' + fileName);
    });
});

--index.html--

<!DOCTYPE html>
<!--[if lt IE 7]><html lang="en" class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]><html lang="en" class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]><html lang="en" class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--><html lang="en" class="no-js">
<!--<![endif]-->

<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>My AngularJS App</title>
<script src="js/angular.js"></script>
<script src="js/angular-route.js"></script>
<script src="js/angular-resource.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
</head>
<body ng-app="statsApp">

    <div ng-controller="StatisticsCtrl">

        <form>
            Enter The Desired Date: <input type="date" name="drDate"
                ng-model="drDate.current" ng-change="dateChanged()"><br>
            <input type="submit" value="Submit">
        </form>

        <ul class="menu">
            <li><a href="#/statistics">Statistics</a></li>
            <li><a href="#/transactions">Transactions</a></li>
        </ul>

    </div>


    <div ng-view></div>

</body>
</html>

--statistics.html--

<DIV ng-controller="StatisticsCtrl">
    <TABLE border="1">
        <TR>
            <TD colspan="100%">Statistics For: {{drDate.current}}</TD>
        </TR>
        <TR>
            <TD colspan="100%">{{message}}</TD>     // This is for debug purposes... 
        </TR>
        <TR>
            <TD colspan="100%">{{filename}}</TD>    // This is for debug purposes... it updates as expected
        </TR>
        <TR ng-repeat="stats in statistics.items" ng-model="statistics.items" > // This ng-repeat does not get updated :-\
            <TD>{{stats.send_method}}</TD>
            <TD>&nbsp;</TD>
            <TD>{{stats.count}}</TD>
        </TR>
        <TR>
            <TD colspan="100%">Total number of statistics:
                {{statistics.items.length}}</TD>
        </TR>
        <TR>
            <TD colspan="100%">ServiceURL :         // This is for debug purposes... it updates as expected
                {{fileName}}</TD>
        </TR>
    </TABLE>
</DIV>

Upvotes: 0

Views: 214

Answers (1)

JB Nizet
JB Nizet

Reputation: 691625

You have two different instances of the StatisticsCtrl. Each has its own copy of the statistics and of the date. One is used in the main page (index.html), containing the input field:

<div ng-controller="StatisticsCtrl">

and the other is in the statistics view:

<DIV ng-controller="StatisticsCtrl">

So, when the date changes in the outer controller, the outer scope's date is changed, and the statistics of the outer scope are modified. But the statistics of the inner scope are left unchanged.

You shouldn't have 2 instances of the controller. Leave the date handling in an outer controller, of a different type, and in the inner controller, use a watch on the date, or listen for events broadcasted by the outer controller, to reload the stats every time the data changes.

Upvotes: 1

Related Questions