Reputation: 2766
I have a question conserning the use of services or factories inside an AngularJS application.
I Want to write a service that will return data from an Api which i can use inside my controllers.
Lets say i want to have a call like $scope.people = myPeopleService.getPeople();
and inside my service want to check if i already have people and return those otherwise i want to do a $http.get()
and fill the people inside my service and then return them. I do not want to have .then
inside my controller. Is this even possible?
Upvotes: 2
Views: 1511
Reputation:
If you dont want to return the promise to the consumer of your service:
.service('...', function ($http) {
var cachedResponse;
this.getStuff = function () {
if (cachedResponse) {
return cachedResponse;
}
return $http.get('someUrl')
.then(function (response) {
cachedResponse = response;
return response; // Return the response of your $http call.
});
};
});
Upvotes: 2
Reputation: 31761
You won't be able to escape that at some level, somewhere, this call is asynchronous. One part of your question is easy, caching data is just an option in the $http
call:
$http.get(url, {cache: true})
If you expose this call from a service only one call will be made over the network, no changes are required in your controller code.
Another thing to look into is using your router's resolve
feature (ui-router and the vanilla router both support resolve). This can clean up some of the code in your controller.
Upvotes: 1
Reputation: 15984
My solution is to return a reference to an object that might be empty at first, but will hold the data eventually:
app.factory('myPeopleService', function($http){
var people = {};
$http
.post( "/api/PeopleService/getInitData", {
}).success(function (data, status, headers, config) {
angular.extend(people, data);
}).error(function (data, status, headers, config) {
});
return {
getPeople: function () {
return people;
}
};
});
the key is to use angular.extend in order to preserve the object reference.
in the controller you can use ng-show until the data is fulfilled, and/or use watch for processing
Upvotes: 2
Reputation: 2578
It is not possible to do it without a .then
in your use case. Since you want to make use of $http
to fetch the people and return them (if they were not present already). $http
works asynchronously and would return a promise. Due to the asynchronous behavior of $http
it becomes mandatory to handle the promise returned in the calling function.
Hope this helps!
Upvotes: 0