I have a $resource
whose API will always return some data that needs to be cleaned up before going into the presentation layer. Specifically, it's .NET returning Date objects in the lovely '/Date(...)/'
format.
I don't want to have to write a callback every time I call .query()
or .get()
. Is there some way to extend the resource with a callback that gets called upon REST methods that update the instance's properties, or by adding some sort of $watch
that gets fired when the date property changes? Basically something that will happen for every instance of this $resource
.
angular.module('myAppServices', ['ngResource'])
.factory('Participant', ['$resource', function ($resource) {
var res = $resource('api/url/participants/:id', { id: '@id' });
// This obviously doesn't work, but something kinda like this?
res.prototype.$watch(this.FieldName, function(newVal, oldVal) {
if (needsCleaning(newVal.fieldName) {
this.FieldName = cleanupField(newVal);
}
};
});
Ah-ha, I found a way around it and will leave it here. In version 1.1.2 they added support for passing all the $http.config
options to a $resource
. Naturally, the CDN I'm using doesn't have a recent enough version of angular-resource.js, but switching CDNs solved that.
I just used the transformResponse
option to modify the data as it comes back.
angular.module('myAppServices', ['ngResource'])
.factory('Participant', ['$resource', '$http', function ($resource, $http) {
var res = $resource('api/url/participants/:id', { id: '@id' }, {
save: {
method: 'POST',
transformResponse: $http.defaults.transformResponse.concat([
function (data, headersGetter) {
data.FieldName = yourDateParsingFunction(data.FieldName);
return data;
}
])
}
});
I'm just adding my transformer on to $httpProvider
's transformResponse, which will do all the deserialization, etc.
An easy way to do this is to overwrite the existing $resource
methods you want to do post-processing on with your own. See the code and comments below for an example.
angular.module('myAppServices', ['ngResource'])
.factory('Participant', ['$resource', function ($resource) {
var res = $resource('api/url/participants/:id', { id: '@id' }, {
// create aliases for query and get to be used later
_query: { method: 'GET', isArray: true },
_get: { method: 'GET' }
});
// redefine the query method
res.query = function() {
// call the original query method via the _query alias, chaining $then to facilitate
// processing the data
res._query.apply(null, arguments).$then(function(res) {
var data = res.data;
// do any processing you need to do with data here
return data;
});
};
// redefine the method
res.get = function() {
// call the original get method via the _get alias, chaining $then to facilitate
// processing the data
res._get.apply(null, arguments).$then(function(res) {
var data = res.data;
// do any processing you need to do with data here
return data;
});
};
return res;
});
You'd use it the same way you're currently using Participant
in your code, via Participant.query()
or Participant.get()
. The data you return in the chained $then handler will be used to resolve the promise returned by $resource
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With