0

In my Controller, I'm quering data from a $resource object bundled in a caching service.

$scope.data = myService.query(); //myService caches the response. 

In the same controller I have the configuration for a chart (for the GoogleChartingDirectve).

$scope.chart = {
      'type': 'AreaChart',
      'cssStyle': 'height:400px; width:600px;',
....
      'rows' : convert($scope.data),
...
}

convert is just a function which takes the data from myService and returns an array for the chart.

This is only working, if the response of the query has already been cached (After changing the route, I can see the graph, but if I call the route directly it is empty).

Perhaps the problem is my caching?

angular.module('webApp')
  .service('myService', function myService($cacheFactory,res) {
    var cache = $cacheFactory('resCache');

   return {
      query: function() {
         var data = cache.get('query');
         if (!data) {
            data = res.query();
            cache.put('query', data);
         }
         return data;
      }
   };

});

I've tried the $scope.$watch in my Controller. It is fired only once with no data. If I change to a different route and back again it is fired again; this time with data.

$scope.$watch('data',function(newValue){
      console.log("Watch called " + newValue);
}

I'm not sure what the problem actually is. It looks like the $watch event is missing.

If I call the refresh with a button, $watch is fired and data is shown.

$scope.refresh = function(){
      $scope.data = $scope.data.concat([]);
}

I'm just an angular newbie and playing around in a small demo project. So I'm looking for the best way to solve some common problems.

Any idea how to solve my problem?

StarsSky
  • 6,721
  • 6
  • 38
  • 63
KEB
  • 13
  • 3

1 Answers1

0

I guess the problem is that you are not aware that res.query() is an asynchronous call. The $resource service works as follow: the query call returns immediatly an empty array for your data. If the data are return from the server the array is populated with your data. Your $watch is called if the empty array is assigned to your $scope.data variable. You can solve your problem if you are using the $watchCollection function (http://docs.angularjs.org/api/ng.$rootScope.Scope):

$scope.$watchCollection('data', function(newNames, oldNames) {
  var convertedData = convert($scope.data);
  ...
});

Your cache is working right. If you make your server call later again you got the array with all populated data. Btw. the $ressource service has a cache option (http://docs.angularjs.org/api/ngResource.$resource) - so you don't need to implement your own cache.

You may ask why the $ressource service works in that way - e.g. returning an empty array and populating the data later? It's the angular way. If you would use your data in a ng-repeat the data are presented to the view automatically because ng-repeat watches your collection. I guess you chart is a typical javascript (for example jQuery) that doesn't watch your data.

michael
  • 16,221
  • 7
  • 55
  • 60
  • with $scope.$watchCollection i can react on changes as needed. So its working now :) I will have a look at the $ressource cache as well. But I think in this case it's better for me to use the service. I will share the data between three controllers and I will add some more magic to the service. – KEB Feb 02 '14 at 19:06