Search code examples
javascriptangularjsangular-resourceangularjs-resource

AngularJS: transform response in $resource using a custom service


I am trying to decorate the returned data from a angular $resource with data from a custom service. My code is:

angular.module('yoApp')
  .service('ServerStatus', ['$resource', 'ServerConfig', function($resource, ServerConfig) {
    var mixinConfig = function(data, ServerConfig) {
      for ( var i = 0; i < data.servers.length; i++) {
        var cfg = ServerConfig.get({server: data.servers[i].name});
        if (cfg) {
          data.servers[i].cfg = cfg;
        }
      }
      return data;
    };

    return $resource('/service/server/:server', {server: '@server'}, {
      query: {
        method: 'GET',
        isArray: true,
        transformResponse: function(data, header) {
          return mixinConfig(angular.fromJson(data), ServerConfig);
        }
      },
      get: {
        method: 'GET',
        isArray: false,
        transformResponse: function(data, header) {
          var cfg = ServerConfig.get({server: 'localhost'});
          return mixinConfig(angular.fromJson(data), ServerConfig);
        }
      }
  });
}]);

It seems I am doing something wrong concerning dependency injection. The data returned from the ServerConfig.get() is marked as unresolved. I got this working in a controller where I do the transformation with

ServerStatus.get(function(data) {$scope.mixinConfig(data);});

But I would rather do the decoration in the service. How can I make this work?


Solution

  • 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
      };
    });