I am having issues rendering Flotcharts with data populated from an AngularJS (v1.2.5) service call. When the data is hard-coded, the charts render as expected but not when assigned the value from a $resource call (console logging shows "undefined" as the value).
The odd thing is that the same variable I use to populate the chart data is displayed in the view and works fine which makes me think this could be some sort of race condition or scoping issue.
I have tried assigning the the $scope variables as a result of resolved promises without success to remedy race conditions as well as tried things such as $scope.$apply() from the chart directive.
Below are code excerpts from my application. Any help is appreciated. Thank you.
HTML wrapper:
<!DOCTYPE html>
<html data-ng-app="app" data-ng-controller="app">
<head>
<title>FlotChart Example</title>
</head>
<body>
<main data-ng-view></main>
</body>
</html>
Template from Overview route:
<div class="chart-title">{{getCount.count}} Total Transactions</div>
<div id="deposits" data-chart="pie" data-flot-chart data-ng-model="model" data-ng-controller="OverviewCtrl"></div>
Main Module ("app"):
;(function (angular) {
'use strict';
angular.module('app', ['ngRoute', 'ngResource', 'ngTouch', 'services.Localization', 'Login', 'Overview'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/login.html',
controller: 'LoginCtrl'
})
.when('/overview', {
templateUrl: 'views/overview.html',
controller: 'OverviewCtrl'
})
.otherwise({
redirectTo: '/'
});
}])
.controller('App', ['$rootScope', 'Localize', function ($rootScope, Localize) {
// initialize localization
$rootScope.labels = Localize.get();
}]);
}(angular));
Overview Controller (used in charts and view):
;(function (angular) {
'use strict';
angular.module('Overview', ['services.DepositsSvc'])
.controller('OverviewCtrl', ['$rootScope', '$scope', 'DepositCount', 'DepositCountGET', function ($rootScope, $scope, DepositCount, DepositCountGET) {
$scope.getCount = DepositCount.get();
$scope.getGETCount = DepositCountGET.get();
$scope.model = {};
$scope.model.data = [
{
label: $rootScope.labels.gets,
data: $scope.getGETCount.count,
color: "#e4d672"
},
{
label: $rootScope.labels.puts,
data: $scope.getCount.count,
color: "#c2cfeb"
}
];
$scope.model.options = {
series: {
pie: {
show: true,
radius: 1,
label: {
radius: 2/3,
formatter: function (label, series) {
return '<div class="pie">' + label + ': ' +
series.data[0][1] + '<br>(' + Math.round(series.percent) + '%)</div>';
}
}
}
},
legend: {
show: false
}
};
}]);
}(angular));
Services (output from both calls is { count: number }):
;(function (angular) {
'use strict';
angular.module('services.DepositsSvc', ['ngResource', 'ngRoute'])
.factory('DepositCount', ['$resource', function ($resource) {
return $resource('/rest/deposits/count', {}, {
query: { method: 'GET', params: {}, isArray: true }
});
}])
.factory('DepositCountGET', ['$resource', function ($resource) {
return $resource('/rest/deposits/countgetdeposits', {}, {
query: { method: 'GET', params: {}, isArray: true }
});
}]);
}(angular));
Charts directive:
;(function (angular, $) {
'use strict';
angular.module('directives.FlotCharts', [])
.directive('flotChart', function () {
return {
restrict: 'EA',
controller: ['$scope', '$attrs', function ($scope, $attrs) {
var plotid = '#' + $attrs.id,
model = $scope[$attrs.ngModel];
$scope.$watch('model', function (x) {
$.plot(plotid, x.data, x.options);
});
}]
};
});
}(angular, jQuery));
Solution documented at AngularJS Google Group.