AngularJS: transform response in $resource using a custom service
It is not possible to use the transformResponse to decorate the data with data from an asynchronous service. I posted the solution to http://jsfiddle.net/maddin/7zgz6/.
Here is the pseudo-code explaining the solution:
angular.module('myApp').service('MyService', function($q, $resource) { var getResult = function() { var fullResult = $q.defer(); $resource('url').get().$promise.then(function(data) { var partialPromises = []; for (var i = 0; i < data.elements.length; i++) { var ires = $q.defer(); partialPromisses.push(ires); $resource('url2').get().$promise.then(function(data2) { //do whatever you want with data ires.resolve(data2); }); $q.all(partialPromisses).then(function() { fullResult.resolve(data); }); return fullResult.promise; // or just fullResult } }); }; return { getResult: getResult };});
Well, Its actually possible to decorate the data for a resource asynchronously but not with the transformResponse
method. An interceptor
should be used.
Here's a quick sample.
angular.module('app').factory('myResource', function ($resource, $http) { return $resource('api/myresource', {}, { get: { method: 'GET', interceptor: { response: function (response) { var originalData = response.data; return $http({ method: 'GET', url: 'api/otherresource' }) .then(function (response) { //modify the data of myResource with the data from the second request originalData.otherResource = response.data; return originalData; }); } } });
You can use any service/resource instead of $http
.
Update:
Due to the way angular's $resource interceptor is implemented the code above will only decorate the data returned by the $promise and in a way breaks some of the $resource concepts, this in particular.
var myObject = myResource.get(myId);
Only this will work.
var myObject;myResource.get(myId).$promise.then(function (res) { myObject = res;});