I have an application built using AngularJS and a server-side backend that delivers all requests in JSON form. Each and every request is wrapped in a JSON container that contains a data variable which contains the data specific to the request. The other data, which are used to keep state and control within the application, check for errors and success messages, and check for session flags. All of these other variables are served with EVERY request and are examined first before the data variable is.
Right now I have a method to examine the contents of the JSON response first and then the data itself.
$http.get('something.json').success(function(response) {
var data = examineJSONResponse(response);
//do the data stuff
});
This works and the examineJSONResponse takes a look at the code and if there is something wrong then it throws an exception and reloads the page using window.location.href.
Is there any way that I can automate this within AngularJS so that each time a $http call is made then it checks this and ONLY returns the data variable contents as the JSON response?
You can intercept responses by adding an interceptor to $httpProvider.interceptors
with Angular 1.1.4+ (see documentation here search for interceptors).
For a specific content type like json you can potentially reject changes or throw an exception even if the call was a success. You can modify the response.data
that will get passed to your controller code as well here:
myModule.factory('myHttpInterceptor', function ($q) {
return {
response: function (response) {
// do something on success
if(response.headers()['content-type'] === "application/json; charset=utf-8"){
// Validate response, if not ok reject
var data = examineJSONResponse(response); // assumes this function is available
if(!data)
return $q.reject(response);
}
return response;
},
responseError: function (response) {
// do something on error
return $q.reject(response);
}
};
});
myModule.config(function ($httpProvider) {
$httpProvider.interceptors.push('myHttpInterceptor');
});
NOTE: Here is the original answer for versions prior to 1.1.4 (responseInterceptors
were deprecated with Angular 1.1.4):
Maybe there's a better way but I think you can do something similar to this post with the http response interceptor (described here) (for a specific content type like json) where you potentially reject changes or throw an exception even though the call was a success. You can modify the response.data
that will get passed to your controller code as well here.
myModule.factory('myHttpInterceptor', function ($q) {
return function (promise) {
return promise.then(function (response) {
// do something on success
if(response.headers()['content-type'] === "application/json; charset=utf-8"){
// Validate response if not ok reject
var data = examineJSONResponse(response); // assumes this function is available
if(!data)
return $q.reject(response);
}
return response;
}, function (response) {
// do something on error
return $q.reject(response);
});
};
});
myModule.config(function ($httpProvider) {
$httpProvider.responseInterceptors.push('myHttpInterceptor');
});
Another solution is to create a service and use that around the $http variable.
angular.module('App', [])
.factory('myHttp',['$http',function($http) {
return function(url, success, failure) {
$http.get(url).success(function(json) {
var data = examineJSONResponse(json);
data && data.success ? success() : failure();
}).error(failure);
);
}
}]);
And now this can be called like:
myHttp(url, onSuccess, onFailure);