Reputation: 314
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
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
ng-bind
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
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
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