0

I have a similar situation like in AngularJS : Initialize service with asynchronous data, but I need to inject my base service with asynchronous data into depend services. It looks like this:

Base service:

angular.module('my.app').factory('baseService', baseService);

baseService.$inject = ['$http'];

function baseService($http) {
    var myData = null;

    var promise = $http.get('api/getMyData').success(function (data) {
        myData = data;
    });

    return {
        promise: promise,
        getData: function() {
            return myData;
    }};
}

Dependent service (in which I inject base service)

angular.module('my.app').factory('depentService', depentService);

depentService.$inject = ['baseService'];

function depentService(baseService) {
    var myData = baseService.getData();
    ....

    return {...};
}

Route:

    angular.module('my.app', ["ngRoute"])
    .config(function ($routeProvider) {
        $routeProvider.when('/',
            {
                resolve: {
                    'baseService': function (baseService) {
                        return baseService.promise;
                    }
                }
            });
    });

But nothing happens, baseService.getData() still returns null (coz async api call still in progress). Seems like my ngRoute config is invalid, but I cant indicate any controller/template into it. How can I correctly resolve my baseService and get data in Depend service?

2
  • Why not register the service with angular and then inject it into the component/controller where needed? Then just call the method to get the data as a promise. This would be the standard approach that most angularjs devs take and any experienced angularjs dev will be able to read your code (if done that way). Commented Mar 27, 2020 at 17:34
  • Igor, you totally right.your suggestion is right way to deveplop modern application. Currently all services returns objects with data, so I cant easily change it to promises. In this case I will need to change structure of whole legacy UI application (20+ controllers, 200+ service calls). This is unacceptable for me. Commented Mar 27, 2020 at 21:56

1 Answer 1

2

Dependent services should work with promises and return promises:

angular.module('my.app').factory('depentService', depentService);

depentService.$inject = ['baseService'];

function depentService(baseService) {
    ̶v̶a̶r̶ ̶m̶y̶D̶a̶t̶a̶ ̶=̶ ̶b̶a̶s̶e̶S̶e̶r̶v̶i̶c̶e̶.̶g̶e̶t̶D̶a̶t̶a̶(̶)̶;̶
    var promise = baseService.promise;
    
    var newPromise = promise.then(function(response) {
        var data = response.data;
        //...
        var newData //...
        return newData;
    }); 

    return newPromise;
}

To attempt to use raw data risks race conditions where the dependent service operates before the primary data returns from the server.

From the Docs:

The .then method returns a new promise which is resolved or rejected via the return value of the successCallback, errorCallback (unless that value is a promise, in which case it is resolved with the value which is resolved in that promise using promise chaining).

AngularJS $q Service API Reference - The Promise API

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.