Reputation: 337
I've created a directive for plotting bar charts with Morris. It does plot the bar charts when I hard code the values. But I'm not able to plot the charts with values received from an http response. I'm new to javascript, angularjs etc.
Module:
var sampleApp = angular.module('sample',[]);
Directive:
sampleApp.directive('barchart', function() {
return {
restrict: 'E',
template: '<div></div>',
replace: true,
link: function($scope, element, attrs) {
var data = $scope[attrs.data],
xkey = $scope[attrs.xkey],
ykeys= $scope[attrs.ykeys],
labels= $scope[attrs.labels];
var setData = function(){
console.log('inside setData function');
Morris.Bar({
element: element,
data: data,
xkey: xkey,
ykeys: ykeys,
labels: labels
});
};
// The idea here is that when data variable changes,
// the setData() is called. But it is not happening.
attrs.$observe('data',setData);
}
};
});
Controller:
sampleApp.controller('sampleController',function($scope, $http){
$scope.xkey = 'range';
$scope.ykeys = ['total_tasks', 'total_overdue'];
$scope.labels = ['Total Tasks', 'Out of Budget Tasks'];
$scope.myModel = [
{ range: 'January', total_tasks: 5, total_overdue: 5 },
{ range: 'January', total_tasks: 35, total_overdue: 8 },
{ range: 'January', total_tasks: 20, total_overdue: 1 },
{ range: 'January', total_tasks: 20, total_overdue: 6 }
];
$http({method: 'GET', url: '../test/executeTest'}).
success(function(data, status, headers, config) {
// here I would populate myModel with values from above url.
// But for simplicity, I'm just hardcoding the values(changed slightly) again.
$scope.myModel = [
// changing just one value in first row.
{ range: 'January', total_tasks: 25, total_overdue: 5 },
{ range: 'January', total_tasks: 35, total_overdue: 8 },
{ range: 'January', total_tasks: 20, total_overdue: 1 },
{ range: 'January', total_tasks: 20, total_overdue: 6 }
];
console.log('success ' + $scope.myModel[0].total_tasks);
}).
error(function(data, status, headers, config) {
console.log('error');
});
});
html:
<html>
<head>
<script src="lib/jquery-1.8.2.min.js"></script>
<script src="lib/angular.min.js"></script>
<script src="lib/raphael-min.js"></script>
<script src="lib/morris.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body ng-app="sample" ng-controller="sampleController">
<barchart xkey="xkey" ykeys="ykeys" labels="labels" data="myModel"></barchart>
</script>
</body>
</html>
I read somewhere that I should not be using observers if the value does not contain curly braces like {{..}}. But I don't know how to fix it with watchers or any other thing.
Upvotes: 1
Views: 3698
Reputation: 21
answer https://stackoverflow.com/a/22063220/2266630 - $digest problem
replace
$scope.$apply()
for
$timeout(function(){
$scope.$apply();
});
[1] - $timeout - https://coderwall.com/p/udpmtq
[2] - $apply - http://jimhoskins.com/2012/12/17/angularjs-and-apply.html
Upvotes: 1
Reputation: 337
I was able to resolve this issue. I added the below code to my directive:
$scope.$watch(function() {
return $scope.myModel}, setData);
and added the below code to my controller after changing the scope.myModel
$scope.$apply();
After these changes, I see that the graph is updated with new values. But it gave an exception in the console:
Error: [$rootScope:inprog] http://errors.angularjs.org/1.2.13/$rootScope/inprog?p0=%24digest
Anyway, since it shows me the output I want, it unblocked me for now.
Upvotes: 0