Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS Intercept all $http JSON responses

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?

like image 980
matsko Avatar asked Aug 14 '12 16:08

matsko


2 Answers

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'); }); 
like image 173
Gloopy Avatar answered Oct 23 '22 13:10

Gloopy


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); 
like image 32
matsko Avatar answered Oct 23 '22 12:10

matsko