0

I've been trying to make a cubism.js graph with polled data (every second) from REST API.

It seems like a correct value is passed to the directive, but it is not passed to an anonymous callback function.

If I am understanding correctly, the anonymous callback function in directive should have an access to the parameter variable val.

The correct value is updated in the view, and the rest of the directive. However, right now it seems like the parameter value, val, which was updated from the controller when the promise resolves to a callback function notifyCall(data), is not being updated at an anonymous callback function of directive.

Methods I tried:

  • putting the random function inside of notifyCallback function in the controller.
    -> didn't work
  • wrapping $scope.$apply on $scope.sysHeapMemoryPercent
    -> $digest error
  • using scope.watch in the directive instead of attrs.$observe
    -> had a same result as attrs.$observe method

How can I solve this problem? Do I need to use a closure?

Controller

'use strict';
angular.module('adminControllers')
.controller('pollerController', ['$scope', '$resource', 'poller', function ($scope, $resource, poller) {

  $scope.sysHeapMemoryPercent=0;

  // ......
  // Some codes that makes polling API calls every second
  // using $resource and Angular Poller
  // ......

  myPoller.promise.then({}, {}, notifyCallback); 

  function notifyCallback(data){
    $scope.sysHeapMemoryPercent = Number(data[0].value.used) / Number(data[0].value.max);
    }
}]);

Directive

'use strict';
angular.module('adminControllers')
 .directive('sysHeapMemoryDirective', function ($timeout) {

 return {
 restrict: 'AE',
 link: function (scope, element, attrs) {
    var context = cubism.context().serverDelay(0).clientDelay(0).step(1000).size(594);


  attrs.$observe('memory', function (newVal,oldVal) {
    console.log(oldVal); // prints undefined every second
    console.log(newVal); // prints the correct value every second

    var constantNum = 0.123;
    compute(constNum); // works
    compute(newVal); // Doesn't work. Some child values are returned as null
  });


  function compute(val) {
    var value = 0, values = [],
    i = 0, last; 

    console.log(val); // prints the correct value every second

    return context.metric(function (start, stop, step, callback) {
      start = +start, stop = +stop;

      console.log(val); // prints 0 every second

      if (isNaN(last)) last = start;
      while (last < stop) {
        last += step;
        values.push(val);
      }
      callback(null, values = values.slice((start - stop) / step));
    }, "Demo");
  }
}
};
});

HTML

<div ng-controller="pollerController">
 {{sysHeapMemoryPercent}}  // successfully shows the updated value every second
   <sys-heap-memory-directive memory="{{sysHeapMemoryPercent}}"> </sys-heap-memory-directive>
</div>
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
SJ Lee
  • 11
  • 2
  • I'm not sure if I understand exactly. Is it `sysHeapMemoryPercent` that is not updating? I'd try wrapping the assignment statement in a call to `$timeout(function(){ ... }); – Trevor Aug 15 '14 at 19:16
  • sysHeapMemoryPercent was updating correctly, but the anonymous callback function, compute(val), did not read the updated value from the parameter because it was not an OBJECT. For some reason, when I wrapped the variable as an object, it worked. – SJ Lee Aug 16 '14 at 00:00

1 Answers1

1

I'm not sure if I'm allowed to answer my own question, but I found the solution as I was trying other ways to solve the problem.

The problem here is that AngularJS's "dirty-checking" is based on objects, and I was trying to save $scope.sysHeapMemoryPercent as a primitive type (number) not an object.

This link helped me a lot to understand how AngularJS updates scope variables behind the scene. Auto-updating scope variables in angularjs

When I wrapped my response as an object, it worked fine!

$scope.sysHeapMemoryPercent={};
// .............
function notifyCallback(data){
  $scope.sysHeapMemoryPercent.value = Number(data[0].value.used) / Number(data[0].value.max);
}
Community
  • 1
  • 1
SJ Lee
  • 11
  • 2