3

I have an AngularJS application where I have services that calls $http resource and returns a promise that I resolve in my controller. Here's a sample of what I'm doing:

app.service('Blog', function($http, $q) {
  var deferred = $q.defer();
  $http.get('http://blog.com/sampleblog')
    .then(function(res) {
        // data massaging stuffs
      return deferred.resolve(res.data);
    }, function(err) {
        // may be some error message checking and beautifying error message
      return deferred.reject(err);
    });
    // chain if further more HTTP calls
  return deferred.promise;
});

But I could simply do the following as well:

app.service('Blog', function($http) {
  return $http.get('http://blog.com/sampleblog');
});

And then do the validation, error beautifying, chaining promises, etc. at the controller level.

My question is : Which is considered as 'best practice', if any, in terms of code resiliency and flexibility? Or is there a better way to do it completely different than this ?

Charlie
  • 22,886
  • 11
  • 59
  • 90
Prashant Ghimire
  • 4,890
  • 3
  • 35
  • 46
  • 2
    IMO it is better to leave validation, error beautifying, chaining promises, etc. in the service, because you can use the service from different controllers, in this way you do not duplicate the code – rpadovani Jul 11 '16 at 15:02
  • 2
    [.then](https://docs.angularjs.org/api/ng/service/$q#the-promise-api) returns a new promise so you do not have to explicitly use the `$q` service since it is basically doing the same thing. –  Jul 11 '16 at 15:09
  • @ProfessorAllman what if I have some data massaging logic ? Like is it considered good to do `$scope.post = someMethod(res.data[0]);` or `$scope.error = if (res.err.details.code === 400) doThis(); else doThat();` – Prashant Ghimire Jul 11 '16 at 15:18

1 Answers1

5

As per the concept behind MVC, controller should decide what to do with the promise.

The service should initiate the promise.

app.service('Blog', function($http) {
  return $http.get('http://blog.com/sampleblog');
});

And the controller should decide what to do when resolved.

$scope.response = Blog;

$scope.response.then(function(response) {
    DataProcessor.processData(response.data)
})
.error(function(error){
    ErrorHandler.handle(error);
})
Charlie
  • 22,886
  • 11
  • 59
  • 90
  • 1
    I will take it. Liked how you introduced the concept of `DataProcessor` and `ErrorHandler`. Fair enough :) – Prashant Ghimire Jul 11 '16 at 15:37
  • 1
    @PrashantGhimire You see the practicality of this approach (which I learned from others) is that controller can initiate the process, and set various flags. Then it can decide what to do when the response arrives. You shouldn't pack this up inside a service unless it is required very specifically. Good question ;) – Charlie Jul 11 '16 at 15:42