I made a base class, HttpService:
class HttpService
constructor: (url) ->
@service = $resource url, {}, @actionOptions()
actionOptions: ->
query:
method: 'GET'
isArray: true
transformResponse: (data) =>
response = []
wrapped = angular.fromJson(data)
angular.forEach wrapped[@indexRoot], (item) =>
response.push @jsonToModel(item)
response
I inherit like this:
class FooService extends HttpService
constructor: ->
super '/api/foos/:id'
@indexRoot = 'foos'
all: ->
@service.query()
jsonToModel: (data) ->
new Foo(data)
In general, the idea is to extend HttpService providing the URL of the resource and the index root (JSON has a root element for the index action). I override jsonToModel
to provide a way to transform each JSON element in the response into a custom object, in this case Foo
.
When debugging, I can see that response
is what it should be in actionOptions()
, so it seems like transformResponse
is returning what I expect, an array of Foo
s.
Whenever I call FooService.all()
though, I get an array of Resource
s (ngResource default)... anyone have any idea what I'm doing wrong? I've omitted the dependency injection and everything, but it's all working and I have no errors in console.
The $resource service wraps the response in Resource objects using an interceptor, which occurs after the transformResponse, so while transformResponse is a good place to unwrap a root object (the results from there get fed into the interceptors), you will also need an interceptor to call your jsonToModel function.
The relevant docs:
https://docs.angularjs.org/api/ngResource/service/$resource
transformResponse – {function(data, headersGetter)|Array.} – transform function or an array of such functions. The transform function takes the http response body and headers and returns its transformed (typically deserialized) version. By default, transformResponse will contain one function that checks if the response looks like a JSON string and deserializes it using angular.fromJson. To prevent this behavior, set transformResponse to an empty array: transformResponse: []
interceptor - {Object=} - The interceptor object has two optional methods - response and responseError. Both response and responseError interceptors get called with http response object. See $http interceptors.