Angular 1 - Want to intercept only Remote server calls - 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);
}
};
});

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

Define default action when $http returns certains status

Is it possible to set a default action for $http in my app?
The idea would be that if any $http call in a controller, or service of my app would return 405, I could change to state 'login'
Something like this (of course this will not work at all, but I guess that shows the idea)
angular.module('app',[]).config(function($http){
$http.error(function(error,state){
if (state===405){
do stuff
}
);
You can use interceptors to achieve this.
// register the interceptor as a service
$provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
return {
// optional method
'request': function(config) {
// do something on success
return config;
},
// optional method
'requestError': function(rejection) {
// do something on error
if (canRecover(rejection)) {
return responseOrNewPromise
}
return $q.reject(rejection);
},
// optional method
'response': function(response) {
// do something on success
return response;
},
// optional method
'responseError': function(rejection) {
// do something on error
if (canRecover(rejection)) {
return responseOrNewPromise
}
return $q.reject(rejection);
}
};
});
$httpProvider.interceptors.push('myHttpInterceptor');
// alternatively, register the interceptor via an anonymous factory
$httpProvider.interceptors.push(function($q, dependency1, dependency2) {
return {
'request': function(config) {
// same as above
},
'response': function(response) {
// same as above
}
};
});
Read more about it here
You should do something like this:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
//Do whatever you want on success
}, function errorCallback(response) {
if(response.status == 405) {
//Go to login
}
});
Below code might help you:
$http.get("url")
.success(function (data, status, headers, config) {
$scope.content = data;
if (data == '405') {
$state.go('login', {id: the_necesarry_id});
}
else {window.alert(' ');}
})
.error(function (data, status, headers, config) {
});
use angularjs Interceptors
// interceptors.js
.factory('httpInterceptor', function ($q, $injector) {
return {
'requestError': function(rejection) {
// do something on error
if(rejection.status === 405){
$injector.get('$state').transitionTo('login');
}
return $q.reject(rejection);
},
'responseError': function(rejection) {
// do something on error
if(rejection.status === 405){
$injector.get('$state').transitionTo('login');
}
return $q.reject(rejection);
}
};
});
// app.js
app.config( function ($httpProvider, $interpolateProvider, $routeProvider) {
$httpProvider.interceptors.push('httpInterceptor');
...
});

ui router if resolve fails why do load the view

May be I miss something but
if I set a state like this:
.state('session_register', {
url: '/privatearea',
resolve: {
isLogged: function(Session){
return Session.isLogged();
}
},
templateUrl: 'private/user.html',
controller:'UserController'
})
if isLogged return a 401 status (resolve fails)
even if I don't really see the user.html in the browser
the partial is just loaded (firebug)
So I'm wondering
Is it the wanted behaviour ?
Is there a way to not load partial
when a resolve fails ?
I've got also an httpInterceptor
.factory('httpInterceptor', ['$q', '$location',
function($q, $location) {
return {
'response': function(response) {
if (response.status === 401) {
$location.path('/auth/login');
return $q.reject(response);
}
return response || $q.when(response);
},
'responseError': function(rejection) {
if (rejection.status === 401) {
$location.url('/auth/login');
return $q.reject(rejection);
}
return $q.reject(rejection);
}
};
}
])
//Http Interceptor to check auth failures for XHR requests
.config(['$httpProvider',
function($httpProvider) {
$httpProvider.interceptors.push('httpInterceptor');
}
]);
END UP
.factory('httpInterceptor', ['$q','$location',function ($q,$location) {
var canceller = $q.defer();
return {
'request': function(config) {
// promise that should abort the request when resolved.
config.timeout = canceller.promise;
return config;
},
'response': function(response) {
return response;
},
'responseError': function(rejection) {
if (rejection.status === 401) {
canceller.resolve('Unauthorized');
$location.url('/user/signin');
return $q.reject(rejection);
}
if (rejection.status === 403) {
canceller.resolve('Forbidden');
$location.url('/');
return $q.reject(rejection);
}
return $q.reject(rejection);
}
};
}
])
//Http Intercpetor to check auth failures for xhr requests
.config(['$httpProvider',function($httpProvider) {
$httpProvider.interceptors.push('httpInterceptor');
}]);
it works :)
I think it is by design. Apart from an extra bandwidth, there is no need to block the template loading, otherwise the view will complete slower.
And there is no way to change this behavior too. From the source code:
https://github.com/angular-ui/ui-router/blob/0.2.10/src/state.js#L1158
dst.resolve = $resolve.resolve(state.resolve, locals, dst.resolve, state);
var promises = [ dst.resolve.then(function (globals) {
dst.globals = globals;
}) ];
if (inherited) promises.push(inherited);
// Resolve template and dependencies for all views.
forEach(state.views, function (view, name) {
var injectables = (view.resolve && view.resolve !== state.resolve ? view.resolve : {});
injectables.$template = [ function () {
return $view.load(name, { view: view, locals: locals, params: $stateParams, notify: false }) || '';
}];
promises.push($resolve.resolve(injectables, locals, dst.resolve, state).then(function (result) {
// References to the controller (only instantiated at link time)
if (isFunction(view.controllerProvider) || isArray(view.controllerProvider)) {
var injectLocals = angular.extend({}, injectables, locals);
result.$$controller = $injector.invoke(view.controllerProvider, null, injectLocals);
} else {
result.$$controller = view.controller;
}
// Provide access to the state itself for internal use
result.$$state = state;
result.$$controllerAs = view.controllerAs;
dst[name] = result;
}));
});
// Wait for all the promises and then return the activation object
return $q.all(promises).then(function (values) {
return dst;
});
A promise from state.resolve:
$resolve.resolve(state.resolve, locals, dst.resolve, state);
and $view.load (which make a http request for the templateUrl):
$view.load(name, { view: view, locals: locals, params: $stateParams, notify: false })
not wait for each other to finished first, it happens in pararell, and used in the return statement:
return $q.all(promises).then(function (values) {
Hope this clear things up.

httpInterceptor Angularjs: change $http request files to requirejs

$provide.factory('myHttpInterceptor', function($q) {
return {
// optional method
'request': function(config) {
return config;
},
// optional method
'requestError': function(rejection) {
// do something on error
console.log(config);
return $q.reject(rejection);
},
// optional method
'response': function(response) {
// do something on success
return response;
},
// optional method
'responseError': function(rejection) {
// do something on error
//if (canRecover(rejection)) {
// return responseOrNewPromise;
//}
return $q.reject(rejection);
}
};
});
$httpProvider.interceptors.push('myHttpInterceptor');
I want when client request file '.html', it won't call to server ever. Instead I will use requireJS. How can I response this data from requirejs to client?

Capture HTTP 401 with Angular.js interceptor

I'd like to implement authentication on a single page web app with Angular.js. The official Angular documentation recommends the using of interceptors:
$provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
return {
// ...
'responseError': function(rejection) {
// do something on error
if (canRecover(rejection)) {
return responseOrNewPromise
}
return $q.reject(rejection);
}
};
});
The problem is when the server sends 401 error, the browser immediately stops with "Unauthorized" message, or with login pop-up window (when authentication HTTP header is sent by the server), but Angular can't capture with it's interceptor the HTTP error to handle, as recommended. Am I misunderstanding something? I tried more examples found on web (this, this and this for example), but none of them worked.
For AngularJS >1.3 use $httpProvider.interceptors.push('myHttpInterceptor');
.service('authInterceptor', function($q) {
var service = this;
service.responseError = function(response) {
if (response.status == 401){
window.location = "/login";
}
return $q.reject(response);
};
})
.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('authInterceptor');
}])
in app config block:
var interceptor = ['$rootScope', '$q', "Base64", function(scope, $q, Base64) {
function success(response) {
return response;
}
function error(response) {
var status = response.status;
if (status == 401) {
//AuthFactory.clearUser();
window.location = "/account/login?redirectUrl=" + Base64.encode(document.URL);
return;
}
// otherwise
return $q.reject(response);
}
return function(promise) {
return promise.then(success, error);
}
}];
I don't know why, but response with 401 error goes into success function.
'responseError': function(rejection)
{
// do something on error
if (rejection.status == 401)
{
$rootScope.signOut();
}
return $q.reject(rejection);
},
'response': function (response) {
// do something on error
if (response.status == 401) {
$rootScope.signOut();
};
return response || $q.when(response);
}
AngularJS interceptors only work for calls made with the $http service; if you navigate to a page that returns a 401, AngularJS never even runs.

Resources