Alessio Rossotti
Alessio Rossotti

Reputation: 314

AngularJS view not refreshed after model change

I'm displaying some data on a table using Angular and I'm loading it asynchronously from json with $http. I have a date-picker and when the user selects a different date, the view has to display the data for that date. The problem is that even if the new data is correctly loaded, the view is not refreshed. Here is my code (I simplified including only important lines):

<tbody>
    <tr ng-repeat="row in tableKPI"> 
        <td ng-repeat="index in tableKPIColsInt">{{ row[index]}}</td>
        <td ng-repeat="index in tableKPIColsFloat">{{ row[index] | number:2}}</td>
    </tr>
</tbody>

Where tableKPIColsInt and Float are just lists of strings with column names.

loadDailyDataFromJSON = function ($plantName,$http,$scope,$timeout) {

    var formattedDate = dateFormat($scope.selectedDate,"yyyy-mm-dd");

    $http.get("json/"+formattedDate+".json")
    .then(function (response) {
        $scope.tableKPI = response.data[$plantName];
    },
    function(error) {
        $scope.tableKPI = {};
        console.log("No data for KPI for "+formattedDate);
    });

    // tried also to call $apply
    $timeout(function() { $scope.$apply();}, 500);
};

And the controller:

app.controller("tableController", function($scope,$routeParams,$rootScope,$http,$timeout){
    $scope.tableKPI = {};
    $scope.reloadData = function(){
        loadDailyDataFromJSON($rootScope.currentPlant,$http,$scope, $timeout);
    };

}

This code works the first time I load the page, then if I change the date the new data is loaded correctly, but the view doesn't change. I know that there are many similar questions, but the solution doesn't work for me. I tried calling $scope.$apply(), but it gives me the error digest already in progress.. I tried also to call $apply() after a timeout, but I obtain the same result.

[UPDATE] putting the function inside / outside the controller or in a service doesn't change anything.. The function is being called and the data in the variable is updated.

Maybe there is a problem with the model? As I do a double nested loop and I take both the info for displaying (one iterates over the rows and one over the string indexes). If I put this code specifying the controller nothing works:

<tbody ng-controller="dailyCtrl as dc">
    <tr ng-repeat="row in dc.tableImbalance"> 
        <td ng-model="row[index]" ng-repeat="index in dc.tableImbalanceCols" ng-bind-html="row[index].toString()"></td> 
    </tr>
</tbody>

Upvotes: 1

Views: 2152

Answers (3)

Andreq Frenkel
Andreq Frenkel

Reputation: 1208

You don't need $timeout or $scope.$apply when you are using $http service. This functionality already implemented inside $http service.

Make sure you used your controller right.

This is an example with your code:

http://jsfiddle.net/jgyombzg/5/

When you click Reload you will see what data updated.

[UPDATED]

Due question update I think the reason is ng-bind-html Take a look into fiddle again - you can see 2 ng-repeat

  • in 1 case i just used ng-bind
  • in 2 case i used ng-bind-html

Second is empty as you can check.

Can you try do the same? If you will have same result - $sce might help

Upvotes: 1

Abdullah Al Noman
Abdullah Al Noman

Reputation: 2878

Refactor it like this

 app.controller("tableController", function($scope,$routeParams,$rootScope,$http,$timeout){
    $scope.tableKPI = {};
    $scope.reloadData = function(){
        loadDailyDataFromJSON($rootScope.currentPlant,);
    };


  // assuming the function is in same file as controller 
    loadDailyDataFromJSON = function ($plantName) {

        var formattedDate = dateFormat($scope.selectedDate,"yyyy-mm-dd");

        $http.get("json/"+formattedDate+".json")
        .then(function (response) {
            $scope.tableKPI = response.data[$plantName];
        },
        function(error) {
            $scope.tableKPI = {};
            console.log("No data for KPI for "+formattedDate);
        });

    };

}

But if you prefer the service approach

app.service("testService", function($http){

 this.loadDailyDataFromJSON = function ($username) {

     var endpoint = "rooturl"+"json/"+formattedDate+".json";
      return $http({
        method: 'get',
        url: endpoint 
      });
    };

}

And in controller

 app.controller("tableController", function($scope,$routeParams,$rootScope,testService{
        $scope.tableKPI = {};
        $scope.reloadData = function(){
            var formattedDate = dateFormat($scope.selectedDate,"yyyy-mm-dd");

            testService.loadDailyDataFromJSON (formattedDate)
            .then(function (response) {
                $scope.tableKPI = response.data[$plantName];
            },
            function(error) {
                $scope.tableKPI = {};
                console.log("No data for KPI for "+formattedDate);
            });
        };


    }

If formattedDate is not null and you have used the correct rooturl then this will work like charm

Upvotes: 3

Sujatha
Sujatha

Reputation: 302

Put loadDailyDataFromJSON in angularservice and inject the same into your controller and start using it. then apply is not required as am using the same concept in my application. it is perfectly working without apply

Upvotes: 0

Related Questions