4

This should be a fairly straight forward question, but I'm stumped.

I have a service that makes an http call and then does extensive post-processing of the results. I would like the processed results to be assigned to a $scope.variable and used in several different views. The thing is I have separate controllers for each view, but I don't want each controller to call the service to have the same data fetched from a resource and post-processed once for each controller.

Super simplified I have this:

myModule.factory ('Data', function ($http, $q) {
  getData: $http.get...
  processData: this.getData().success(function(data){
    ... do a ton of cpu intensive processing ... 
    return processed_data
ctrl1 = function(Data,$scope) {
  $scope.data = Data.processData()
  }
ctrl2 = function(Data,$scope) {
  $scope.data = Data.processData()
etc...
}

Obviously I would like to set $scope.data = Data.processData() just once and have it populate across all the controllers. As it stands, each controller invokes the service independently, which creates unnecessary traffic and cpu.

I'm sure there is something simple, but I can't figure it out. Is there some way of creating a "super" scope where I can define variables that are common to all controller scope?

Thanks,

MyTimeFinder
  • 1,787
  • 4
  • 23
  • 28
  • You can share data between controllers by creating a service [as described here](http://stackoverflow.com/questions/12008908/pass-variables-between-controllers) – Gloopy Apr 17 '13 at 05:40

1 Answers1

6

I see you've injected the $q service. Why don't you just return a promise (just like $http.get...) in your Data service that resolves when the cpu intensive processing is done? You could also do like the angular $resource service and return an empty object that gets populated once the processing is done (in the following example I assume that processed_data is an array, but it would also work for an object):

myModule.factory ('Data', function ($http, $q) {
  var deferred = $q.defer();
  var futureResult = [];
  //will get populated once processing is done, and is basically a cache

  $http.get('url').success(function(data){
    //... do a ton of cpu intensive processing ...
    for(var i=0; i<processed_data.length; i++){
      futureResult[i] = processed_data[i];
    }
    deferred.resolve(futureResult);
  });

  return {
    getProcessedDataPromise:function(){
     return deferred.promise;
    }
    ,getProcessedData:function(){
      return futureResult;
    }
  }
});

In the controllers

ctrl1 = function(Data,$scope){
  Data.getProcessedDataPromise().then(function(data){
    $scope.data = data;
  });
}
ctrl2 = function(Data,$scope){
  $scope.data = Data.getProcessedData();
}

You can also have a look at this plnkr example.

joakimbl
  • 18,081
  • 5
  • 54
  • 53