0

I have a service on my angular.js app that creates a variable (filteredDataGlobal) in it's scope (self) and has another function to return that variable.

.service('Utilities',function(){
    var self = this;

    self.someFunction = function(){
      ///does calculations then assigns the results in a variable (filteredDataGlobal)
      self.filteredDataGlobal = finalResults;
    }

    self.getFilteredData = function(){
        return self.filteredDataGlobal;
    };

}

The problem is self.someFunction takes time to happen (calculations made after an http request) so that when you're in a controller that has the Utilities service and try to access the self.filteredDataGlobal variable like so, it's logged as undefined

.controller('MyController', function(Utilities) {

    var self = this;

    self.filteredData = Utilities.getFilteredData();

    console.log(self.filteredData);

})

How would I 'watch' for self.filteredDataGlobal to be ready in the Utilities function before I use it in my controller?

NewToJS
  • 2,011
  • 4
  • 35
  • 62

2 Answers2

0

there are 3 methods that i know of.

  1. callbacks
  2. promises(preferred)
  3. broadcast and eventHandlers

1- you put the code in a function and pass that into your service, then run that function when your variable has been prepared. something like:

.controller(..function(..){
    $scope.callback= function(){
        ....
    }
    someService.someFunction(params, callback);
})

and in your service: .service(...function(..){ var someVar = value; callback(); })

2- use the promise api to return a promise from your service into your controller. and use the .done function to know when the service has returned the data.

.service(.., ['$q',.., function($q,..){
    var dfd = $q.deffered;
    if(someVar == set)
        dfd.resolve;
    else
        dfd.reject;
    return dfd.promise;
}])

and in cotroller:

.controller(..function(..){
    someService.someFunction(..).then(function(){
    });
});

3- create an event in service. and broadcast it to rootScope. then check it in your controller to see if that particular event has occurred with .on. then run the controller code(that uses that variable).

.service(..function(..){
    someFunction(){
        $rootScope.someVar = value;
        $rootScope.broadcast('event-name');
    }
})

and in your controller:

.controller(..function(..){
    $rootScope.on('event-name', function(events, args){
        //use the variable someVar here.
    }
})

Note: this is not an actual code that you can copy/paste and use, it's just to give you the idea of how it works. hope it helps :)

Mridul Kashyap
  • 704
  • 1
  • 5
  • 12
  • Ok, but for #2 I'm getting an error: Can't find variable: $q – NewToJS Aug 08 '16 at 12:48
  • `$q` is service. you need to inject it in your service before you can use it. i've updated the answer. check again. and as i said, this code is not ready-to-use. you'll still need to find bits and pieces from google. the code only shows the basics of "how to go about doing it". – Mridul Kashyap Aug 08 '16 at 12:52
0

I agree with Mridul Kashyap answer. but I want to add something regarding point 2 that you can do as following:

app.controller("MyController", MyController); 

function MyController($scope, selectedService){
   selectedService.$promise.then(function(data){
  $scope.myData = data; 
  //fill your logic here. 
   }
} 

if you do like that, you ensure that you fill your $scope variables when the promise is resolved

Nadeem Khoury
  • 886
  • 6
  • 18