4

I'm trying to resolve a couple ajax calls so that data my controller needs is available before it (and a directive it furnishes) execute. The order of execution is working, however, instead of returning the object I create, the result injected into my controller is $http's response object:

{
  config: { … },
  data: { … },
  headers: { … },
  status: 200
}

My code essentially looks like:

app.config([
  '$routeProvider', function($routeProvider)
  {
    $routeProvider
      .when('/path', {
        …,
        "resolve": {
          "data": [
            '$http',
            function($http)
            {
              return $http
                .get('/api/data')
                .success(function(data,status) { return data.rows[0]; })
                .error(function(data,status)   { return false; });
            }
          ]
        }
      });
  }
]);

Am I daft? Shouldn't the return value from $http's success actually be what is returned by $http?

I also tried

…
"resolve": {
  "data": [
    '$http',
    function($http)
    {
      var response;
      $http
        .get('/api/data')
        .success(function(data,status) { response = data.rows[0]; })
        .error(function(data,status)   { response = false; });
      return response;
    }
  ]
}

But then the data object injected into my controller was undefined (I'm guessing because $http is asynchronous and resolve was not blocked by $http—so it returned before $http was ready).

P.S. The synchronicity of $http should be definable in its options object!!

Solution

app.config([
  '$routeProvider', function($routeProvider)
  {
    $routeProvider
      .when('/path', {
        …,
        "resolve": {
          "data": [
            '$http',
            function($http)
            {
              return $http
                .get('/api/data')
                .then(
                  function success(response) { return response.data.rows[0]; },
                  function error(reason)     { return false; }
                );
            }
          ]
        }
      });
  }
]);

Thanks to Ajay beniwal's pointer and Mark Rajcok's pointer.

P.S. then() is documented on $q's page.

Community
  • 1
  • 1
Jakob Jingleheimer
  • 30,952
  • 27
  • 76
  • 126
  • 1
    You need to return a promise. See http://stackoverflow.com/questions/11972026/delaying-angularjs-route-change-until-model-loaded-to-prevent-flicker, the community wiki answer. – Mark Rajcok Jul 17 '13 at 17:49
  • I was previously using `$http.get('…').then()` (which I think is a `$promise` method) but I need `success` and `error` methods (which I don't see for `then`. (I really don't want to set an arbitrary delay/timeout—just continue when its done, grr). – Jakob Jingleheimer Jul 17 '13 at 18:06
  • If the answer is in there, why not post it as an actual answer? – user1338062 Mar 11 '15 at 12:40

1 Answers1

2

$http @returns {HttpPromise} Returns a {@link ng.$q promise} object with the standard then method and two http specific methods: success and error. The then method takes two arguments a success and an error callback which will be called with a response object. The success and error methods take a single argument - a function that will be called when the request succeeds or fails respectively. The arguments passed into these functions are destructured representation of the response object passed into the then method. The response object has these properties:

Ajay Beniwal
  • 18,857
  • 9
  • 81
  • 99
  • Would be great if an example of how to use `then` and its callbacks was given in the docs :/ – Jakob Jingleheimer Jul 17 '13 at 18:07
  • Ohh, there's an example in `$q`'s docs – Jakob Jingleheimer Jul 17 '13 at 18:09
  • "promise which is resolved or rejected via the return value of the successCallback, errorCallback (unless that value is a promise, in which case it is resolved with the value which is resolved in that promise using promise chaining)." https://github.com/angular/angular.js/blob/master/src/ng/q.js#L317 TLDR–return whatever you want from $q.then successCallback/errorCallback mentioned above in the **Solution** above. – chemoish Jun 10 '15 at 01:23