Search code examples
javascriptangularjspromiseangular-resource

How do I get the results of a promise into a scoped variable manually upon promise resolution?


Assume for discussion that I'm building a stock ticker app and I need prices to update every 2 seconds, I have a $resource wrapped over calls to a WebApi, and $scoped variables on my controller that maintain the results of those $resource calls.

I'm working from a modification of the sample in the Angular documentation for $interval. The major difference is that inside my interval, I am updating a $scoped variable to the results of a $resource.

I've been working with Angular's automatic promise resolution for binding my variables, but now that I've got my symbols updating on an interval, the data wipes each time the interval is fired and doesn't display until the promise resolves, so I get a "windshield wiper effect" on my View. What I really want is for the "old data" to display until the promise returns, at which time, the results will be stuffed into my scoped variable and the view rebound.

What would be the simplest way to do this with the following code?

I tried introducing an intermediate variable, assigning it to the promise from $resource.Bars() and registering a success callback inside the interval, but the success callback never fires.

'use strict';
var ctrls = angular.module('MyModule',[]);
ctrls.controller('FooCtrl', ['$scope', '$location','$interval','$document','service',
  function( $scope,$location,$interval,$document,service)
  {
     var stop;
$scope.Bars = {};
$scope.Baz = service.Baz; //Note that angular resolves this promise automatically.
$scope.pollService = function(){
   if(angular.isDefined(stop))return;
   stop = $interval(function(){
     if(service){
        $scope.Bars = service.Bars();
     }
   },1000);
};
$scope.stopPolling = function(){
   if(angular.isDefined(stop)){
     $interval.cancel(stop);
     stop = undefined;
   }
};
$scope.$on('$destroy',function(){
 $scope.stopPolling();
    });
    $document.ready(function(){
       $scope.pollService(); 
    });
  }


var app = angular.module('MyModule.Services',['ngResource']);
app.service('service', ['$resource', function($resource)
{
    var proxy = $resource(
    'http://server/subsystem/api/Foo/:component',
    {},
    {
        Bars: {method:'GET',isArray:false,url: 'http://server/subsystem/api/Foo/Bars'
       ,Baz: {method:'GET',isArray:false,rul: 'http://server/subsystem/api/Foo/Baz'
    }
    return proxy;
}]);

Edit

A colleague was able to assist me shortly after I posted my question. I was trying to register a success callback through .then() on the promise and that is apparently incorrect. The success callback can be put directly inside the service.Bars() call as the first argument. So, in this case, my code became

$scope.pollService = function(){
   if(angular.isDefined(stop))return;
   stop = $interval(function(){
     if(service){
        service.Bars(function(data){
            if(data) $scope.Bars = data;
        });
     }
   },1000);
};

Solution

  • service.Bars(function(data){
       if(data)$scope.Bars = data;
    });
    

    was the droid I was looking for