Reputation: 1526
I am trying to initialize my applications services before the controller starts running.
I would have thought that i could achieve this by resolving a promise-returning function first:
va.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {templateUrl: '../partials/home.php', controller: 'VaCtrl',resolve: {
pp: vac.loadData
}});
}]);
var vac = va.controller('VaCtrl',function($scope,$http,$q,packingProvider){
console.dir(packingProvider.data[2]);
});
vac.loadData = function($http,$timeout,$q,packingProvider){
$http.post('../sys/core/fetchPacking.php').then(function(promise){
packingProvider.data = promise.data;
});
var defer = $q.defer();
$timeout(function(){
defer.resolve();
},2000);
return defer.promise;
};
However, the controller is still loaded before the promise has beenr esolved, resulting in the console yelling
Cannot read property '2' of undefined
at me.
What am i doing wrong?
Edit:
Also, the controller seems to get invoked twice, first time with the undefined pacingProvider.data object, and 2 secons later with everything fine.
Upvotes: 0
Views: 5857
Reputation: 871
Instead of using the promise
returned by $timeout
, you could directly use the promise
returned by $http
.
Rewrite your loadData
fn this way -
vac.loadData = function($http,$timeout,$q,packingProvider){
var promise = $http.post('../sys/core/fetchPacking.php').then(function(promise){
packingProvider.data = promise.data;
});
return promise;
};
Read the first line in the General Usage
section here - $http promise
Also, resolve
is a map of dependencies.
resolve - {Object.=} - An optional map of dependencies which should be injected into the controller. If any of these dependencies are promises, the router will wait for them all to be resolved or one to be rejected before the controller is instantiated.
Hence, Angular will automatically expose the map for injection. So, you can do this -
var vac = va.controller('VaCtrl', function($scope, pp){
// 'pp' is the name of the value in the resolve map for $routeProvider.
console.dir(pp[2]);
});
Upvotes: 3
Reputation: 23394
NOTE: although this will solve your problem, this answer is probably the right solution.
Services are always initialized before controllers. The problem, as you stated, is that your promise hasn't resulted yet. The best option for that is to stick to the promises.
Instead of exposing the data
object, expose the promise and use it:
vac.loadData = function($http,$timeout,$q,packingProvider){
packingProvider.data = $http.post('../sys/core/fetchPacking.php');
return packingProvider.data;
};
And in your controller, always attached to the promise, after the first resolval, it will get resolved in the next tick:
var vac = va.controller('VaCtrl',function($scope,$http,$q,packingProvider){
packingProvider.data.then(function(value) {
console.dir(value[2]);
});
});
Upvotes: 3