0

I'm designing an API client with angular and the $http service using a Hypermedia API. Since I have resources that build on top of each other I wanted the client user to be able to do this declaratively:

apiRoot
    .getPeopleRoot()
    .getPerson(1)
    .addJob(apiRoot.getJobsRoot().getRandomJob())
    .updatePerson()

But I want to also be able to tap in $then methods to use intermediate results:

$scope.job = apiRoot.getJobsRoot().getRandomJob()

apiRoot.getPeopleRoot().getPerson(1).then(function (person) {
    $scope.person = person
}).addJob($scope.job).updatePerson()

I managed to do each one of these separately by returning the promise or an object that contains the functions to operate with each of these resouces but I'm not sure how to achieve both at the same time, or if it's a good idea.

EDIT: I managed to progress using the following mixin to my resource objects

function Actualizable() {}
Actualizable.prototype.actual = function (value) {
  this.realizedValue = value
  return this
}

Then checking if I've resolved the value on each function or calling a promise to actually resolve it. I'm not sure if there's a mechanism to do this with promises still.

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
Pedro Montoto García
  • 1,672
  • 2
  • 18
  • 38

1 Answers1

0

To chain promises, return values (or another promise).

apiRoot.getPeopleRoot().getPerson(1).then(function (person) {
    $scope.person = person;
    //return the value to chain
    return person;
})

Because calling the .then method of a promise returns a new derived promise, it is easily possible to create a chain of promises

It is possible to create chains of any length and since a promise can be resolved with another promise (which will defer its resolution further), it is possible to pause/defer resolution of the promises at any point in the chain.

-- AngularJS $q Service API Reference -- Chaining Promises

Also see Angular execution order with $q

Community
  • 1
  • 1
georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • So that doesn't allow me to call `add job` on the return of `then` (which is not person, but a promise to person). Alternatively, If I change the prototype of the promise to be able to call `addJob`, how do I know if the caller is person or a promise to a person? – Pedro Montoto García Feb 23 '16 at 21:37
  • I don't recommend adding methods to a promise. The AngularJS team added `.success` and `.error` methods to promises returned from the `$http` service and that caused lots of problems. The AngularJS team subsequently decided to deprecate those methods. – georgeawg Feb 23 '16 at 22:29
  • 1
    The `$resource` service returns an object with a property named `$promise` which holds the promise which later resolves to the fulfilled object. I like that approach better. – georgeawg Feb 23 '16 at 22:35