3

I use ngResource to query a JSON service and per default Angular parses the response. Unfortunately I'd also like to have access to the raw response string.

Here is a snippet of what I'd like to achieve:

var app = angular.module('plunker', ['ngResource']);

app.factory('DateResource', function($resource, $http) {
  var raw = null,
    resource = $resource('http://date.jsontest.com/', {}, {
      query: {
        method: 'GET',
        transformResponse: [
          function(data) {
            raw = data;
            return data;
          }
        ].concat($http.defaults.transformResponse).concat([
          function(data) {
            data.$raw = raw;
            return data;
          }
        ])
      }
    });
  return resource;
});

app.controller('MainCtrl', function($scope, DateResource) {
  DateResource.query({}, function(response) {
    console.log('response:', response); // should be parsed JSON object
    console.log('response.$raw:', response.$raw); // should be raw JSON string
  });
});

Checkout the full example: http://plnkr.co/edit/RSwrRQFo1dEGDkxzRTcF

This implementation using two transformRequest functions and a raw variable in the parent scope is not really a good idea, since the calls might be asynchronous...

Is there a possibility to identify the response, so I can remember the raw content per response and attach it later in the second transformResponse? Or do you know another solution?

hupf
  • 604
  • 1
  • 6
  • 10

2 Answers2

4

You can do that by overriding the transform defaults and use the angular.fromJson(rawData)

resource = $resource('http://date.jsontest.com/', {}, {
  query: {
    method: 'GET',
    transformResponse: transformGet
  }
});


function transformGet(json, headerGetter) {
  var fromJson = angular.fromJson(json);
  fromJson.json = json ;
  return fromJson;
}

Plunker: http://plnkr.co/edit/uIIdKAeUwRN4ThUlMsvd

Hope that helped

teleaziz
  • 2,220
  • 1
  • 19
  • 25
  • I also thought about doing the JSON parsing in this function, but the reason why I'm looking for another solution is, that in your example, globally defined interceptors/transformators on the `$httpProvider` aren't executed anymore, are they? – hupf Feb 27 '15 at 11:56
  • Alright, I've checked it and it is still possible to have global response interceptors. All that we _override_ is the default transformators and this is fine. Thanks @teleaziz! – hupf Feb 27 '15 at 12:21
-1
 var app = angular.module('plunker', ['ngResource']);

app.factory('DateResource', function($resource, $http) {
  var raw = null,
    resource = $resource('http://date.jsontest.com/', {}, {
      query: {
        method: 'GET',

      }
    });
  return resource;
});

app.controller('MainCtrl', function($scope, DateResource) {
  DateResource.query({}, function(response) {
    console.log('response:', response); // should be parsed JSON object
    console.log('response.$raw:', angular.toJson(response)); // should be raw JSON string
  });
});

see below link for clear understanding:

https://docs.angularjs.org/api/ngResource/service/$resource

  • That's actually the reason I'm asking my question. I'm talking about quite some amounts of JSON data, where `JSON.stringify` becomes a bottleneck... (and technically, it makes no sense to re-serialize the data that has just been parsed). – hupf Feb 26 '15 at 15:47
  • This solution works but the json response is parsed then reserialize. It's better to use transformResponse – LG_ Oct 14 '15 at 10:06