1

I have an Angular service that looks like this:

(function () {
'use strict';

var serviceId = 'currentUserService';
angular.module('app').factory(serviceId, ['common', 'datacontext', currentUserService]);

function currentUserService(common, datacontext) {
    var $q = common.$q;
    var getLogFn = common.logger.getLogFn;
    var logError = getLogFn(serviceId, "error");
    var user = {};

    var service = {
        user: user,
        doesUserHaveFeature: doesUserHaveFeature
    };

    activate();

    return service;

    function activate() {
        var promises = [getCurrentUser()];
        $q.all(promises);
    }

    function getCurrentUser() {
        var deferred = $q.defer();
        datacontext.getLoginInformation().then(function (data) {
            user = data;
            deferred.resolve(data);
        });
        return deferred.promise;
    }

    function doesUserHaveFeature(featureName) {
        debugger;
        var feature = featureName.toLowerCase();

        var result = _.filter(user.features, function(item) {
            var featureString = item.toLowerCase();
            return feature == featureString;
        });

        if (result) {
            return true;
        }

        return false;
    }
}

})();

The service is injected into my Controller and my controller calls the doesUserHaveFeature() method.

However, the doesUserHaveFeature method is called before the promise in the activate method is resolved. Therefore, the user variable is still an empty object.

How can I ensure that the promise in the activate method is returned before the doesUserHaveFeature method is called?

Thanks! Jeremy

jkruer01
  • 2,175
  • 4
  • 32
  • 57

1 Answers1

3

As the user data is retrieved asynchronously, your factory methods are going to have to return promises. Here's how I'd do it...

.factory('currentUserService', function(datacontext) {
    var userPromise = datacontext.getLoginInformation();

    return {
        user: userPromise,
        doesUserHaveFeature: function(featureName) {
            return userPromise.then(function(user) {
                return _.some(user.features, function(feature) {
                    return feature.toLowerCase() === featureName.toLowerCase();
                });
            });
        }
    };
});
Phil
  • 157,677
  • 23
  • 242
  • 245
  • Thanks. This will definitely work. This service will be used throughout the application. I don't want to use promises everywhere in the application. Is there anyway that I can have the doesUserHaveFeature not return a promise? – jkruer01 May 13 '15 at 00:47
  • @Jeremy Have a look at the answers here ~ http://stackoverflow.com/questions/16286605/initialize-angularjs-service-with-asynchronous-data – Phil May 13 '15 at 00:57