TheWebGuy TheWebGuy - 2 months ago 20
AngularJS Question

Angular Factory dependency issue

I have 2 factories: ApiService and LocationService.

In ApiService i'd like to return the endpoint from an $http call that LocationService will use.

But it seems when the controller calls LocationService, it doesn't wait for the response from ApiService. Here is some snippet of code, in ApiService when I finally get it working I will cache it so I won't need to make a server call each time to get the endpoint:

services.factory("ApiService", ["$location", "$http", function ($location, $http) {
return {
getEndpointUrl: function () {
var endpoint;

$http({
method: 'GET',
url: '/site/apiendpoint'
}).then(function successCallback(response) {
endpoint = response.data;
console.log(endpoint);
return endpoint;
}, function errorCallback(response) {
console.error('Error retrieving API endpoint');
});
}
}
}]);


Here is the location service, it consumes ApiService:

services.factory("LocationService", ["$resource", "ApiService", function ($resource, apiService) {
var baseUri = apiService.getEndpointUrl();
return $resource(baseUri + '/location', {}, {
usStates: { method: 'GET', url: baseUri + '/location/us/states' }
});
}]);


When my controller tries to call LocationService.usStates the baseUri is undefined. What am I doing wrong here?

Answer

The reason is because your getEndpointUrl function is asynchronous, and it has no return value.

Since your LocationService uses $resource and depends on on the baseUri, I would suggest bootstrapping that data along with the initial page load and making it a constant like:

angular.module('yourModule').constant('baseUrl', window.baseUrl);

Then your service would inject it to create your resource:

   services.factory("LocationService", ["$resource", "ApiService", "baseUrl", function ($resource, apiService, baseUrl) {
       return $resource(baseUrl + '/location', {}, {
          usStates: { method: 'GET', url: baseUrl + '/location/us/states' }
       });
   }]);