bhavya_w
bhavya_w

Reputation: 10097

Understanding angular $q promise chaining w.r.t particular example

I just a have a simple query related to this piece of code:

Service Code :

function getUser($q, $http) {
  return $http.get('...').then(function(response) {
    return response.data;
  });
}

Controller Code :

// getUser's consuming code
getUser().then(
  function(data) { // Success callback
    // Do something about data
  },
  function(response) { // Error callback
    // How does this error callback gets called ??
  }
);

In case some error occurs in the get users http call. I am not able to understand how ( inner workings ) the error callback gets called in the controller.
The reason I am asking this is because I think we have to call the reject method ( on the deferred object ) in the service then error callback so that the subsequent then error callback ( the one in controller ) is called.

i.e

function getUser($q, $http) {
  return $http.get('...').then(function(response) {
    return response.data;
  },function(response){
    return $q.reject(response)
  });
}

But how does the controller's then error callback is called when we don't return anything from the first then error callback ( the one inside the service ) which corresponds to an error.

Upvotes: 1

Views: 73

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074979

The inner workings are this: then returns a new promise which waits for the original promise to be settled, and

  • if the original is resolved

    • if you've registered a resolution callback, calls your callback and resolves itself with the value the your callback returns

    • if you haven't registered a resolution callback, resolves itself with the original promise's resolution value

  • if the original is rejected

    • if you've registered a rejection callback, calls your callback and rejects itself with the value your callback returns

    • if you haven't registered a rejection callback, rejects itself with the rejection value provided by the original promise

You can imagine the implementation of then being very roughly, conceptually along these lines:

function then(whenResolved, whenRejected) {
    return new Promise(function(resolve, reject) {
        whenOriginalIsResolved(function(resolution) {
            if (typeof whenResolved === "function") {
                try {
                    resolution = whenResolved(resolution);
                } catch (e) {
                    reject(e);
                    return;
                }
            }
            resolve(resolution);
        });
        whenOriginalIsRejected(function(rejection) {
            if (typeof whenRejected === "function") {
                try {
                    rejection = whenRejected(rejection);
                } catch (e) {
                    reject(e);
                    return;
                }
            }
            reject(rejection);
        });
    });
}

Again, that's conceptual, not literal. If you want to see a literal implementation, the original Q by Kris Kowal implements it here. (That's slightly more complex than the lightweight version Angular uses, but it's a good example.)

Upvotes: 1

Related Questions