Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Result of chained HttpPromise should be a HttpPromise and not a Promise #4345

Closed
mren opened this issue Oct 9, 2013 · 3 comments
Closed

Comments

@mren
Copy link

mren commented Oct 9, 2013

Hey.

If I chain two HttpPromise with

return $http.get('/foo').then($http.post('/foo'))

the return value is a Promise and not a HttpPromise.
If chained HttpPromises would still be HttpPromise their usage would be more consistent

Advantages:

  • Simple: On Success the next HttpPromise could be called directly with the body and not with {data, status, header, config}
  • Abstraction: Have all the power of Promises without missing out the features of HttpPromises
  • Consistency: Interacting with chained Requests would be in the same way as with a normal request
@mren
Copy link
Author

mren commented Oct 9, 2013

If I want to chain two HttpPromises and return the same Interface I currently have to do the following:

var getStripeCustomerTokenFromCreditCard = function(creditcard) {
    var deferred = $q.defer();
    var promise = deferred.promise;

    // wrap success and error to return consistent HttpPromise Interface
    // copied from angular.js, removed last parameter config in fn callback
    promise.success = function(fn) {
        promise.then(function(response) {
            fn(response.data, response.status, response.headers);
        });
        return promise;
    };

    promise.error = function(fn) {
        promise.then(null, function(response) {
            fn(response.data, response.status, response.headers);
        });
        return promise;
    };

    createCreditCardToken(creditcard)
        .then(function(token) {
            return createCustomerToken(token.data.id);
        })
        .then(deferred.resolve, deferred.reject);

    return promise;
};

It's a bit long, I need $q, add the success, error boilerplate and then resolve the promise chain.

It would be great if this code could be reduced.
Perhaps I didn't grasp all the concepts and I could drastically reduce the amount of code required to achieve this task.

I wanted to attach some example code to this Issue, so one can see a use case.

Best, Mark

@petebacondarwin
Copy link
Contributor

You can create some helper functions:

function createHandler(fn) {
  function(response) { fn(response.data, response.status, response.headers);
}

function addSuccessAndErrorTo(promise) {
  promise.success = function(fn) {
    promise.then(createHandler(fn));
  };
  promise.error = function(fn) {
    promise.then(null, createHandler(fn));
  };
  return promise;
}

Then your example simplifies to this:

function getCustomerTokenFromCreditCard(creditcard) {
  var promise = createCreditCardToken(creditcard).then(function(response) {
    return createCustomerToken(response.data.id);
  });
  return addSuccessAndErrorTo(promise);
}

@pkozlowski-opensource
Copy link
Member

I think that the proposal from @petebacondarwin is reasonable here. The problem is that there might be many promises created by different handlers in the whole chain - some of the function in a chain might have nothing to do with $http so I don't think we should second-guess that this is "$http promise".

Closing as "won't fix"

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants