Un de mes contrôleurs AngularJS contient cette ligne:
api.tickets.query()
le module api
contient ceci:
angular.module('myapp.api', [
'ngResource'
])
.factory('api', function($resource, applicationsService) {
function fetchAppId() {
return applicationsService.getCurrentApp();
}
return {
tickets: $resource('tickets', {
applicationId: fetchAppId
}),
...
}
applicationsService.getCurrentApp () effectue lui-même un appel $ http. Donc, vous pouvez peut-être voir le problème - cet appel peut ne pas avoir été résolu au moment du retour de fetchAppId ().
Comment puis-je contourner cela?
Disons que les données renvoyées par applicationsService
par une méthode asynchrone sont les suivantes:
var data = [
{
"PreAlertInventory": "5.000000",
"SharesInInventory": "3.000000",
"TotalSharesSold": "2.000000"
}
et applicationsService
factory renvoie promesse:
.factory('applicationsService', ['$resource','$q', function($resource, $q) {
var data = [
{
"PreAlertInventory": "5.000000",
"SharesInInventory": "3.000000",
"TotalSharesSold": "2.000000"
}
];
var factory = {
getCurrentApp: function () {
var deferred = $q.defer();
deferred.resolve(data);
return deferred.promise;
}
}
return factory;
}]);
Je voudrais juste appeler api.tickets()
$scope.data = api.tickets();
mais notre service api
ressemblera à:
.factory('api', function($resource, applicationsService,$q, $timeout) {
function fetchAppId() {
return applicationsService.getCurrentApp();
}
return {
tickets: function() {
var deferred=$q.defer();
fetchAppId().then(function(data) { // promise callback
$timeout(function(){ // added dummy timeout to simulate delay
deferred.resolve(data);
}, 3000);
});
return deferred.promise;
}
}
});
Démo Fiddle
Vous devez faire, c'est créer une promesse vous-même.
.factory('api', function($resource, applicationsService,$q) {
function fetchAppId() {
return applicationsService.getCurrentApp();
}
return {
tickets: function() {
var defer=$q.defer();
fetchAppId().then(function(data) {
var appId=data;
$resource('tickets', {applicationId: appId})
.then(function(data) {
defer.resolve(data);
})
}
return defer.promise;
}
}
Si vous souhaitez attendre qu'une ressource angulaire ($resource
) soit résolue avant le changement d'itinéraire, vous devez renvoyer le $promise
.
$routeProvider.when('/tickets', {
resolve: {
'tickets': function ('Ticket') {
// do this to resolve the async call prior to controller load
return Ticket.query().$promise;
// this will resolve 'tickets' during/after controller load
return Ticket.query();
}
},
controller: ...
});