Pergunta

I have an angular service that talks to a restful webservice.

The restful service has the following methods

  • getManifest
  • login
  • serviceMethod1
  • serviceMethod2
  • ...

The getManifest returns a manifest structure and the login returns an authentication token; both are required to make other serviceMethodX calls but both manifest and auth token needs to be requested only once, meaning they can be requested part of the first serviceMethodX call or can be prefetched before any call but need not be called again for subsequent calls.

I have the following service

'use strict';

myApp.factory('MyService', function($http, $q, ManifestService){

    var manifest = null;
    var authenticationToken = null;

    return {
        getAuthenticationToken: function() {
             var deferred = $q.defer();

            $http.post('/login', authData )
                .success(function(data, status, headers, config){
                    authenticationToken = data.authToken;
                    deferred.resolve(data.authToken);
                });
            return deferred.promise;
    },         
        getManifest: function() {
             var deferred = $q.defer();

            $http.post('/manifest', authData )
                .success(function(data, status, headers, config){
                    deferred.resolve(data.manifest);
                    manifest = data.manifest;
                });
            return deferred.promise;
    },
        makeServiceCall: function(url, data) {
            var deferred = $q.defer();
            // use manifest and authtoken here
            $http.post(url, authData )
                .success(function(data, status, headers, config){
                    deferred.resolve(data);
                });
            return deferred.promise;

        }

    }
});

How can I guarantee manifest and authToken are populated before makeService function is called or how an I chain the promises if they are not populated, just the first time?

Thanks

Foi útil?

Solução

You could have something like a reqsDeferred that keeps the service calls pending until it is resolved. login and getManifest each check if the other resolved before them, and resolve reqsDeferred when so:

'use strict';
myApp.factory('MyService', function($http, $q, ManifestService){

    var manifest = null;
    var authenticationToken = null;

    // [1] Create the deferred requirements object
    reqsDeferred = $q.defer();

    return {
        getAuthenticationToken: function() {
             var deferred = $q.defer();

            $http.post('/login', authData )
                .success(function(data, status, headers, config){
                    authenticationToken = data.authToken;
                    deferred.resolve(data.authToken);

                    //[2] Check for the other to be resolved
                    if (manifest !== null) {
                      reqsDeferred.resolve();
                    }
                });
            return deferred.promise;
    },         
        getManifest: function() {
             var deferred = $q.defer();

            $http.post('/manifest', authData )
                .success(function(data, status, headers, config){
                    deferred.resolve(data.manifest);
                    manifest = data.manifest;

                    //[2] Check for the other to be resolved
                    if (authenticationToken !== null) {
                      reqsDeferred.resolve();
                    }
                });
            return deferred.promise;
    },
        makeServiceCall: function(url, data) {
            var deferred = $q.defer();

            //[3] Keep the calls pending until the promise is satisfied
            reqsDeferred.promise.then( function () {

                // use manifest and authtoken here
                $http.post(url, authData )
                    .success(function(data, status, headers, config){
                        deferred.resolve(data);
                    });

            });

           return deferred.promise;
        }

    }
});
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top