I am trying to set up an interceptor to catch 403 responses.
In my config function I have added this to test things out
$httpProvider.interceptors.push(function($q) {
return {
request: function(config) {
console.log('test');
},
responce: function(responce) {
console.log(responce);
if(responce.status === 403) {
console.log('403')
}
return responce || $q.when(responce);
},
responceError: function(rejection) {
console.log(rejection);
if(rejection.status === 403) {
console.log('403', rejection);
}
return $q.reject(rejection);
}
}
});
When I reload the page I get the following output to console:
TypeError: Cannot read property 'headers' of undefined
test
In an infinite loop that crashes the browser tab
If I remove the request method from the object then I never get anything output to console
I am using Angular version: 1.2.22
The first problem is that your request callback is not returning the config parameter, check the $http interceptors documentation:
request: interceptors get called with a http config object. The
function is free to modify the config object or create a new one. The
function needs to return the config object directly, or a promise
containing the config or a new config object.
The second problem is you are spelling response incorrectly, simply change responce and responceError to response and responseError respectively.
DEMO
$httpProvider.interceptors.push(function($q) {
return {
request: function(config) {
console.log('test');
return config;
},
response: function(response) {
console.log(response);
if(response.status === 403) {
console.log('403')
}
return response || $q.when(response);
},
responseError: function(rejection) {
console.log(rejection);
if(rejection.status === 403) {
console.log('403', rejection);
}
return $q.reject(rejection);
}
}
});
Response is spelled with an s, not with a c.
Related
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
I want to intercepts only remote server calls.
I tried implementing Angular http interceptor but even it is intercepting local template call.
I got every request on console and check request made in Network Tab. It is differ in numbers.
I want reset session timeout on server call
$httpProvider.interceptors.push(function($rootScope) {
return {
'request': function(config) {
return config;
},
'response': function(response) {
return response;
},
'responseError': function(rejection) {
if (rejection.status === 401) {
location.reload();
}
return $q.reject(rejection);
}
};
});
Able to resolve it using $templateCache
Ref - Angular HTTP interceptor executed for embedded ng-templates
Below is the code if someone needed
$httpProvider.interceptors.push(function ($q, $rootScope,$templateCache) {
return {
'request': function(config) {
if( $templateCache.get(config.url) === undefined ){
console.log("Interceptor --> "+ config.url + " -" + $templateCache);
$rootScope.Idle.watch();
console.log(new Date());
}
return config;
},
'response': function (response) {
//Will only be called for HTTP up to 300
console.log(response);
return response;
},
'responseError': function (rejection) {
if(rejection.status === 401) {
location.reload();
}
return $q.reject(rejection);
}
};
});
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
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.
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/