Reputation: 537
I am using ui-router resolve in order to get some data from a service.
The thing is that I need to get a value from the parent $scope in order to call the service as shown bellow.
resolve: {
contactService: 'contactService',
contacts: function ($scope, contactService) {
return contactService.getContacts($scope.parentCtrl.parentObjectId);
}
}
I keep getting Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Also tried a few desperate attempts such as adding scope to the resolve object as shown bellow with not success.
scope: $scope
Any ideas?
Upvotes: 16
Views: 11749
Reputation: 5686
As an alternative to the accepted solution, which requires another round trip to the server for the same resource (if you are getting the value from the server/api) you could $watch
the parent from the child controller.
function ParentController($http) {
var vm = this;
$http.get(someResourceUrl).then(function(res) {
vm.someResource = res.data;
});
}
function ChildController($scope) {
// wait untill the parent gets the value
var unwatch = $scope.$watch('parent.someResource', function(newValue) {
if (newValue) {
// the parent has the value, init this controller
init(newValue);
// dispose of the watcher we no longer need
unwatch();
}
});
function init(someResource) {
// ... do something
}
}
function routerConfig($stateProvider) {
$stateProvider
.state('parent', {
url: '/parent',
controller: 'ParentController',
controllerAs: 'parent',
templateUrl: '...',
})
.state('parent.child', {
url: '/child',
controller: 'ChildController',
controllerAs: 'child',
templateUrl: '...',
});
}
Upvotes: 0
Reputation: 28638
That's impossible, scope hasn't been initialized at that point so you can't use it in the resolve object. You can access the scope in the controller after it's been initialized. The whole point of resolve is that it runs before controller initialization so that you can inject and directly access the resolved items in your scope.
If you need to pass a variable to the next state you can do that by using the $stateParams
object which is available for use in resolve. You can add data to it when changing states, eg:
In your template, if you have a objectId in your scope:
<a ui-sref="statename({'id': objectId})">Change states</a>
Or in your controller:
$scope.go('statename', {'id': $scope.objectId});
You can then retrieve that in your resolve by using the $stateParams
:
resolve: {
contactService: 'contactService',
contacts: function ($stateParams, contactService) {
return contactService.getContacts($stateParams.id);
}
}
Upvotes: 21