0

I'm implementing just a thin wrapper around $http for our REST API, and I'm wanting it to return a promise in the same way as $http does (after I massage the data).

Here's my service:

Services.service('Item', ['$http', '$q', function($http, $q){
    var deferred = $q.defer();
    var getSuccess = function(data, status, headers, config){
        var item = angular.copy(data);
        item.primaryImage = 'https://my.cdn.com/' + item.meta.images[0].s3id;

        if(item.meta.source_link !== null) {
            item.sourceLink = item.meta.source_link.url;
        }

        deferred.resolve(item, data, status, headers, config);
    };
    var getError = function(data, status, headers, config) {
        deferred.reject(data, status, headers, config);
    };

    this.get = function(userID, itemID) {
        $http({
            method: 'GET',
            url: '/api/items/' + userID + '/' + itemID
        }).success(getSuccess).error(getError);

        return deferred.promise;
    };
}]);

But from my understanding of the documentation, I have to use .then(success, error, always) rather than .success().error().always() like I can with $http.

Is it possible to implement promises in the same way that $http does? I would love to do this

var req = Item.get($routeParams.userID, $routeParams.itemID);

req.success(function(item){
        window.console.log('Got an item!', item);
    });
    .error(function(item){
        window.console.log('Damn. It failed.')
    })
Josh Hunt
  • 14,225
  • 26
  • 79
  • 98

1 Answers1

1

This question made me search for a bit after understanding what you actually wanted.

I made a plnkr showing how I solved this: http://plnkr.co/edit/LoCuwk26MEZXsugL1Ki5

Now, the important part is:

var promise = defered.promise;

  promise.success = function(fn) {
    promise.then(function(res) {
      fn(res);
    });
    return promise;
  };

  promise.error = function(fn) {
    promise.then(null, function(err) {
      fn(err);
    });
    return promise;
  };


  return promise

This code comes straight from the angular source code. So I believe it is the way to go if you want to replicate that style.

I did notice an error in your code though. All services are singletons. Which means you only create one deferred object. You should create one on each call and use that.

Neikos
  • 1,840
  • 1
  • 22
  • 35