angular interceptor is not rejected - angularjs

$resource calls some API. If it returns some flag, than request should drop to .catch() section of $resource('api/').get(...).$promise.catch();
My interceptor does not trigger that call. It calls .then in any case
Interceptor code:
.factory('SomeHTTPInterceptor', function($q) {
return {
response: function(response) {
if (response.data.someFlag) {
return $q.reject(response);
}
return response;
}
};
})
How to get same response, but in catch section w/o checking for error in every single request?

You have to use the responseError handler as per doc
responseError: interceptor gets called when a previous interceptor threw an error or resolved with a rejection.
.factory('SomeHTTPInterceptor', ['$q', function($q) {
return {
// optional method
'responseError': function(rejection) {
if (rejection.data.someFlag) {
// do something
}
return $q.reject(rejection);
}
};
}]);

Related

How to handle 401 error in angularjs select2?

I did use an http interceptor to handle 401 response status like following
var expiredSessionInterceptor = function ($q,$window) {
return {
request: function (config) {
return config;
},
requestError: function (rejection) {
// Contains the data about the error on the request and return the promise rejection.
return $q.reject(rejection);
},
response: function (response) {
return response;
},
responseError: function (response) {
if (response.status == 401) {
$window.location.href = '/Cortex_IP/j_spring_security_logout.do';
}
return $q.reject(response);
}
};
};
and it works every other ajax call expect select2 and its not intercepted by the above one .,
The select2 box continue loading (busy) when 401 error occurs.
Any one help me to handle 401 error in select2 in angularjs

Interceptors are not triggered

I'm trying to implement a global authorization handling for my app.
Here you see my code:
.factory('Request', ['$resource', 'general',
function ($resource) {
return $resource(baseURL + ':resourceName/', {}, {
get : {
method : 'GET',
isArray : true,
transformResponse : function (data, headers) {
return JSON.parse(data).data;
},
interceptor: {
request : function (data) {
console.log("test");
},
requestError : function (data) {
console.log("test");
},
response : function (data) {
console.log("test");
},
responseError : function (data) {
console.log("test");
if(data.state == 401){
general.logIn({},false,function(){});
}
}
}
}
});
}
]);
However, none of the interceptors is triggered. What is wrong with code?
According to the Angular documentation, an interceptor when used in $resource only has two valid methods for the interceptor object:
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.
See: https://docs.angularjs.org/api/ngResource/service/$resource
If you require the request methods as well, you would have to follow the documentation here: https://docs.angularjs.org/api/ng/service/$http
Also, I noted that you have defined responseError twice, instead of response and responseError:
responseError : function (data) {
console.log("test");
},
responseError : function (data) {
console.log("test");
if(data.state == 401){
general.logIn({},false,function(){});
}
}
Taken from Angular documentation regarding $resource:
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.
If you'd like to work with all four interceptors I recommend you configure your app with httpProvider. You can push to the interceptors array all 4 possibilities.
Something like this:
m.config(["$httpProvider", ($httpProvider: ng.IHttpProvider) => {
$httpProvider.interceptors.push(["$q" , (q: ng.IQService) => {
return {
'request': (config) => {
..Handle request...
return config;
},
'requestError': (rejection) => {
..Handle requestError...
return $q.reject(rejection);
},
'response': (response) => {
..Handle response...
return response;
},
'responseError': (rejection) => {
..Handle responseError...
return $q.reject(rejection);
}
}
}
]);
}]);
you have missed to insert the "general" into the service function, so the
responseError : function (data) {
console.log("test");
if(data.state == 401){
general.logIn({},false,function(){});
}
}
does not work at all

Angular js interceptor that returns a cached response

I want to make a angularJS interceptor that when the client is offline returns instead of an error a cached response as if it wasn't any error.
What I've done so far was to make an interceptor that caches the api requests:
app.factory('httpCachingInterceptor', function ($q, apiCache) {
return {
'response' : function(response) {
// cache the api
if (response.config.url.indexOf('api/') > 0)
apiCache.addApiCache(response.config.url, response.data);
return response;
},
'responseError' : function(rejection) {
if (rejection.status == -1) {
// get the data from apiCache
//
apiCache.getApiCache(rejection.config.url, function(data) {
// build a new promise and return it as a valid response
})
}
return $q.reject(rejection);
}
}
})
I've noticed that when offline the rejection.status is -1 so that's when I check if a request was made while offline.
My question is how I build the response?
Should I make a new promise or can I update the rejection?
To convert a rejected promise to a fulfilled promise return a value in the onRejection handler.
Conversely, to convert a fulfilled promise to a rejected promise throw a value in the onFulfilled handler.
For more information, see Angular execution order with $q
I managed to make it work like this:
'responseError' : function(rejection) {
if (rejection.status == -1) {
// get the data from apiCache
var deferred = $q.defer();
apiCache.getApiCache(rejection.config.url, function(err, data) {
if (err || !data) {
return deferred.reject(rejection);
}
rejection.data = data;
rejection.status = 200;
deferred.resolve(rejection);
console.log("Resolve promise with ", rejection);
})
return deferred.promise;
}
return $q.reject(rejection);
}
So i made a new promise and modified the rejection I got with the new data from the cache.

uncaughtException "Cannot read property 'info' of undefined" Angularjs

I am trying to add an interceptor in my main config file,below is the code.But I am getting the above error after adding the log. Googled but didn't get much help.Kindly help if anyone faced this error before.
// Intercept http calls.
$provide.factory('HttpResponseInterceptor', ['$q', '$log', function ($q, $log) {
return {
// On request success
request: function (config) {
$log.info('HttpInterceptor Request object' + config); // Contains the data about the request before it is sent.
// Return the config or wrap it in a promise if blank.
return config || $q.when(config);
},
// On request failure
requestError: function (rejection) {
$log.error('HttpInterceptor Request Failure' + rejection); // Contains the data about the error on the request.
// Return the promise rejection.
return $q.reject(rejection);
},
// On response success
response: function (response) {
$log.info('HttpInterceptor Success Response' + response); // Contains the data from the response.
// Return the response or promise.
return response || $q.when(response);
},
// On response failture
responseError: function (rejection) {
$log.error('HttpInterceptor Response Failure' + rejection); // Contains the data about the error.
// Return the promise rejection.
return $q.reject(rejection);
}
};
}]);
$httpProvider.interceptors.push('HttpResponseInterceptor');

AngularJS interceptor

I want to capture all request going out from my one page application like clicking on different tab or any hyperlink.
I have written an interceptor and want to put a ajax call for all request.
.factory('httpRequestInterceptor', function($q,$http){
return {
request: function($http,config){
window.alert(config.url);
var dummyValue = $http.get("url");
return config;
}
}
})
.config(function($httpProvider) {
$httpProvider.interceptors.push('httpRequestInterceptor');
});
I think you are in search of http logger kind of factory. You can use this one
.config(function ($provide, $httpProvider) {
// Intercept http calls.
$provide.factory('MyHttpInterceptor', function ($q) {
return {
// On request success
request: function (config) {
console.log(config); // Contains the data about the request before it is sent.
// Return the config or wrap it in a promise if blank.
return config || $q.when(config);
},
// On request failure
requestError: function (rejection) {
console.log(rejection); // Contains the data about the error on the request.
// Return the promise rejection.
return $q.reject(rejection);
},
// On response success
response: function (response) {
console.log(response); // Contains the data from the response.
// Return the response or promise.
return response || $q.when(response);
},
// On response failture
responseError: function (rejection) {
console.log(rejection); // Contains the data about the error.
// Return the promise rejection.
return $q.reject(rejection);
}
};
});
// Add the interceptor to the $httpProvider.
$httpProvider.interceptors.push('MyHttpInterceptor');
});
I tested, it works for routeProvider navigation as well. For more information please check this blog https://djds4rce.wordpress.com/2013/08/13/understanding-angular-http-interceptors/

Resources