web-dev-qa-db-fra.com

Attendre que la promesse soit résolue avant de charger la ressource

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?

7
Bilal and Olga

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

7
Maxim Shoustin

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;
     }
   }
4
Chandermani

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: ...
});
1
Aleck Landgraf