Reputation: 703
In a project I'm working on we've got a variable on the $rootScope
called events
. I can access this in my controllers using $rootScope.events
after injecting it to my controller.
It can take some time before the service sets the events on the $rootScope
variable. Now am I adding a new functionality that needs the ID from the first event of the variable. The problem is, it's getting called before $rootScope.events
is set. I can't figure out how to call the method in my controller after the $rootscope.events
is set. I have used $watch
before, how ever, it doesn't seem to work on this variable. The code I tried:
$scope.$watch('$rootScope.events', function() {
if ($rootScope.events.length > 0) {
getDetails(); // function I want to call after $rootscope.events is set
$log.debug($rootScope.events); // debugging line
}
});
I added the $rootScope.events.length > 0
to avoid it's getting in a infinite loop. Not sure if this is necessary. Is there a solution for what I need to add this functionality? Something like this watch? Or have I done something wrong?
I don't think you need more code then I've added to this post as I just inject $scope
and $rootScope
in my controller, and then $log.debug()
should get called with the set variable. Currently it returns an empty variable. If I'm wrong just let me know in the comments.
Upvotes: 0
Views: 1946
Reputation: 3142
It's been awhile, but I think you want this:
$rootScope.$watch('events', function() {
if ($rootScope.events.length > 0) {
getDetails(); // function I want to call after $rootscope.events is set
$log.debug($rootScope.events); // debugging line
}
});
events
is a value on $rootscope
but $rootscope.events
is not a value on $scope
.
To avoid cluttering $rootscope
with watches, however, you should probably use:
$scope.$watch('$root.events', function() {
var events = $scope.$root.events;
if (events.length > 0) {
getDetails(); // function I want to call after events is set
$log.debug(events); // debugging line
}
});
Or simply:
$scope.$watch('$root.events', function(newValue, oldValue) {
if (newValue.length > 0) {
getDetails(); // function I want to call after events is set
$log.debug(newValue); // debugging line
}
});
Upvotes: 1
Reputation: 5353
Instead of putting a watch for something that happen once, you can use a promise which your events service will resolve when the events will be ready.
Event Service : ($rootScope & $q injected)
// in constructor :
this.deferred = $q.defer();
$rootScope.eventPromise = deferred.promise;
// in a setup fonction or even within the constructor
setupEvent : function(){
.. doing some stuff ..
.. somewhere in a asynchronous call back :
$rootScope.events =... //setup events
this.deferred.resolve();// or me.deferred using var me=this if some closure trouble
.. somewhere else if it fails ..
this.deferred.reject();
}
Now let's be sure this will run before any controller will be loaded :
angular.run(['EventService', function(EventService){
// if you do everything in the constructor let the angular.run and don't run any code,
// this will make sure your events will start loading before angular will resolve the current routes.
EventService.setupEvent();
}]);
Now let's use it :
$rootScope.eventPromise.then(function(){
$rootScope.events // we're safe here.
});
Upvotes: 0
Reputation: 1316
Watch is on a string (scope variable) or a function.
$scope.$watch(function() {
return $rootScope.events;
}, function() {
console.log($rootScope.events);
}, true);
Upvotes: 0