Get response header in then() function of a ngResource object's $promise property after resource resolved?

StackOverflow https://stackoverflow.com/questions/22898265

Question

I'm willing to retrieve the response header of a resource request, cause I've put pagination information and something else in it rather than the response body, to make the REST api clear.

Though we can get it from the success / error callback like below:

Object.get({type:'foo'}, function(value, responseHeaders){
    var headers = responseHeaders();
});

Where 'Object' is my resource factory service.

Further, when I'm trying to make the route change after required resources resolved, I've tried this:

.when('/list', {
    templateUrl: 'partials/list.html',
    controller: 'ListCtrl',

    // wait for the required promises to be resolved before controller is instantialized
    resolve: {
        objects: ['Object', '$route', function(Object, $route){
            return Object.query($route.current.params).$promise;
        }]
    }
})

and in controller, just inject "objects" instead of Object service, because it's resolved and filled in with real data.

But I got problem when I try to get headers info from the "objects" in controller.

I tried objects.$promise.then(function(data, responseHeaders){}), but responseHeader was undefined.

How can I change the $resource service's behavior so that it throws the responseHeader getter into the $promise then() callback function?

My service "Object" for reference:

myServices.factory('Object', ['$resource',
    function($resource){
        return $resource('object/:id', {id: '@id'}, {
            update: {method: 'PUT'},
        });
    }
]);
Was it helpful?

Solution

I had the exact same problem. I used an interceptor in the resource definition to inject the http headers in the resource.

$resource('/api/resource/:id', {
    id: '@id'
  }, {
    index: {
      method: 'GET',
      isArray: true,
      interceptor: {
        response: function(response) {
          response.resource.$httpHeaders = response.headers;
          return response.resource;
        }
      }
    }});

Then, in the then callback, the http headers are accesible through $httpHeaders:

promise.then(function(resource) {
    resource.$httpHeaders('header-name');
});

OTHER TIPS

I think I had a similar problem: After POSTing a new resource I needed to get the Location header of the response, since the Id of the new resource was set on the server and then returned via this header.

I solved this problem by introducing my own promise like this:

app.factory('Rating', ['$resource',
    function ($resource) {

        // Use the $resource service to declare a restful client -- restangular might be a better alternative
        var Rating = $resource('http://localhost:8080/courserater/rest/ratings-cors/:id', {id: '@id'}, {
            'update': { method: 'PUT'}
        });

    return Rating;
}]);

function RestController($scope, $q, Rating) {
  var rating = new Rating();
  var defer = $q.defer(); // introduce a promise that will be resolved in the success callback
  rating.$save(function(data, headers){ // perform a POST
      // The response of the POST contains the url of the newly created resource
      var newId = headers('Location').split('/').pop();
      defer.resolve(newId)
    });
    return defer.promise;
  })
  .then (function(newId) {
    // Load the newly created resource
    return Rating.get({id: newId}).$promise; // perform GET
  })
  .then(function(rating){
    // update the newly created resource
    rating.score = 55;
    return rating.$update(); // perform PUT
  });
}

We can't use .then for returning the header because the promise doesn't allow for multiple return values. (e.g., (res, err))

This was a requested feature, and was closed https://github.com/angular/angular.js/issues/11056

... the then "callbacks" can have only [one] argument. The reason for this is that those "callbacks" correspond to the return value / exception from synchronous programming and you can't return multiple results / throw multiple exceptions from a regular function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top