The success
and error
handlers are specific to the promise returned by $http
. However, they're similar to .then(function onFulfill(){}, function onReject(){})
.
It's up to you if you want to return that promise directly or implement something else.
Generally, your controller shouldn't be concerned about how your service handled the request. Thus, in my opinion, you shouldn't return that promise directly. Just handle the success and error case in your service. Return the result if the request succeeds and throw an Error if the request fails.
You can then use the generic .then(function onFulfill(){}, function onReject(){})
pattern in your controller, as this is always valid and expected with promises in Angular.
The onFulfill
callback always receives your result as a parameter, the onReject
callback receives the Error as a parameter.
So, what options do you have? Either drop your .success
and .error
callbacks in your service altogether and handle the transformation in the success case in your controller, or create a new deferred promise to return the transformed results:
app.factory('BooksService', function($http,$log,$q) {
var service = {
retrieveAllBooks: function() {
var deferred = $q.defer();
$http({
method: 'GET','https://hugebookstore.org/allbooks'
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
}
}).success(function(data, status, headers, config) {
var allbooks = transformDataIntoBooksArray(data);//this function exists and just takes raw data and turns them into Book objects
deferred.resolve( allbooks );
};
}).error(function(data, status, headers, config) {
$log.error('here is an error'+data + status + headers + config);
deferred.reject( new Error( 'here is an error'+data + status + headers + config );
});
return deferred.promise;
}
};
return service;
});
Although, we can save that if we consider: - Errors are tracked by Angular already - The deferred is excess, and can be avoided - Content-Type and Accept are generated by Angular and the serer anyway. - We can save the anonymous wrapper for our action
So, we end up with:
app.factory('BooksService', function($http) {
return {
retrieveAllBooks: function() {
return $http.get('https://hugebookstore.org/allbooks').
then(transformDataIntoBooksArray); // Error tracked by Angular already
}
}
});