6

So, I've got an Angular app that makes restful calls to the server. There is a service that wraps up the calls to the server. I currently have a method on the service that simply returns the promise from the $http service. I'd like to add some additional processing on that method call, but I'm not sure how to do it because of the asynchronous nature of the promise.

Currently in typescript:

class BoardService {
    private $http;

    constructor($rootScope: IRootScope, $http: ng.IHttpService) {
          this.$http = $http;
    }

    fetchBoard(id: number) {
        return this.$http.get("/api/board/" + id);
    }
}

I'd like to get it to something like this:

fetchBoard2(id: number) {
    this.$http.get("/api/board/" + id).success(function(data)
    {
        // Manipulate the data

    });

    // return manipulated data; 
}

How would you do this?

Darthg8r
  • 12,377
  • 15
  • 63
  • 100

2 Answers2

10

Tricky sentence warning! Because promises are asynchronous, anything returning data based on data from a promise must itself return a promise. You want fetchBoard2 to return a promise that gets resolved once the $http promise has come back and you've manipulated the data. You do this with Angular's $q service.

fetchBoard2(id: number) {
  var deferred = $q.defer();

  $http.get("/api/board/" + id).success(function(data) {
    var newData = doSomething(data);
    deferred.resolve(newData);
  });

  return deferred.promise;
}

Managing extra deferred objects gets quickly fiddly, so you can use then to insert your own manipulation into the pipeline.

fetchBoard3(id: number) {
  return $http.get(...).then(function(data) {
    return doSomething(data);
  });
}

For more detail, here's a good article.

Kristján
  • 18,165
  • 5
  • 50
  • 62
  • 1
    As far as i know, .success() behave the same as .then() and return a derived promise too. return $http.get().success() will work too. – Okazari May 29 '15 at 15:34
  • 3
    Almost - thanks for making me verify this. `success` returns the original promise (containing the HTTP response), and `then` returns a new promise that's resolved with the result of the function you give it. Ref: http://stackoverflow.com/a/23805864/802618 – Kristján May 29 '15 at 15:48
  • 1
    Thx for the addition, didn't now this that precise. – Okazari May 29 '15 at 15:54
  • Asked a question about this. http://stackoverflow.com/questions/30534328/why-do-http-get-success-success-fire-both-success?noredirect=1#comment49142538_30534328 – Okazari May 29 '15 at 16:26
  • 1
    Thanks for clarifying the then/success stuff. – Darthg8r May 29 '15 at 17:00
0

The $http module only exposes the asynchronous version of XMLHttpRequest so the signature you're looking for is impossible. Unless want to fallback to another framework (e.g. jQuery), you'll have to use the Promise object returned.

Think of it as a factory object with which you register handlers that will be called when the data comes back. They can be chained, so if you want to process the data before handing it downstream, you can simply do that in the handler you register with the then method. Any result you return in the handler will become the data to the next then handler.

(Please note that unlike success(), the argument to your handler is the IHttpPromiseCallbackArg type not the data itself.)

billc.cn
  • 7,187
  • 3
  • 39
  • 79