Restangular - $http interceptors - angularjs

Morning,
I have a $http interceptor:
app.factory('Unauthed', ['$q', 'alertService',function($q,alertService) {
return {
response: function (response) {
if (response.status == 401)
alertService.error('Authentication failure.',15000);
return response || $q.when(response);
}
};
}]);
This runs fine for all requests which are going through $http but non which go through Restangular. Looking through the soure Restangular uses $http so I am not sure what is going on here?
Cheers

Maybe the order of execution matters, where are you registering restangular? Also maybe order of dependnecies of angular modules, try declaring restangular as dependency of submodules but not in main app module so that $http is already decorated when you add restangular.

Related

In angular 1.x are interceptors always factories?

I'm trying to wrap my head around interceptors, I still can't figure them out. Can someone explain a tad more for me about if they are a service, a config, etc?
Interceptors can be either a named factory or an anonymous factory.
app.config(function ($httpProvider) {
//register the interceptor factory
$httpProvider.interceptors.push('myHttpInterceptor');
// alternatively, register the interceptor via an anonymous factory
$httpProvider.interceptors.push(function($q, dependency1, dependency2) {
return {
'request': function(config) {
// request transform
},
'response': function(response) {
// response transform
}
};
});
});
Interceptors are registered during the config phase of the AngularJS app. Their factory functions (either named or anonymous) are invoked during the $get phase of the $http service.
For more information, see AngularJS $http Service API Reference - Interceptors

Does Angular1.4 $http include a promise already in the http get? Or do I make my own

I'm a bit confused, the more I read resources online about $q and $http the more my head spins. So if I do a $http.get call does that not include a promise? Or do I bring $q in?
It is built on $q and returns a promise. See the docs: https://docs.angularjs.org/api/ng/service/$http
And the example there:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
$http.get is just a convenience method on the above.
You can refer to the following link
https://www.peterbe.com/plog/promises-with-$http
This service ($http.get()) will return promise as success callback and error callback...so this function itself returns promise. You just have to handle it
The $http API is based on the deferred/promise APIs exposed by the $q
service. While for simple usage patterns this doesn't matter much, for
advanced usage it is important to familiarize yourself with these APIs
and the guarantees they provide.
https://docs.angularjs.org/api/ng/service/$http
Meaning that the $http.get will return a promise anyway. No need nesting your own $q approach. Just return the $http invoke.
$http.get call does that not include a promise? The Answer is Yes, you can return a promise or resolve the promise with $http
Returning a promise from $http.get
getData: function() {
return $http.get('some url'); // you can resolve this promise later
// using (then)
}
So later in your code you can resolve the above promise like this
...
myService.getData().then(function(response) {
// do something with response
}).catch()
Resolve the promise inline
getData: function() {
$http.get('some url').then(function(response) {
// do something with response
}).catch()
}

Inject http into httpProvider in AngularJS

I want to make it so that users are automatically logged out by having the client terminate the session (as opposed to letting the session die on its own). I pushed an interceptor onto the $httpProvider which allows me to set and reset the timeout timer, but the problem is that I can't figure out how to call the logout function which requires $http. This always produces a circular dependency. Is there any way to do this?
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push(
function() {
return {
response: function(response) { $http({ ... }); }
})}
If I make $http a dependency, I get a circular dependency, but without the $http dependency, the call to $http obviously doesn't work.
You should be careful using $http inside an interceptor as it has the potential to cause an infinite loop. Consider refactoring so $http isn't required
That said you can try injecting the $injector instead. Then where you want to make the $http request just use $injector.get('$http')
app.config(['$httpProvider, $injector', function($httpProvider, $injector) {
$httpProvider.interceptors.push(
function() {
return {
response: function(response) { $injector.get('$http') }
})}
You need to inject $http dependancy inside theinceptor.push function, you could also inject other dependencies from there.
Code
app.config(['$httpProvider',
function($httpProvider) {
$httpProvider.interceptors.push(
function($http) { //<--here you could make dependency available.
return {
response: function(response) {
$http({...});
}
})
}])
I used a crossover of the previous answers (use $injector, but in the push() ) to get it working as expected:
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push(function($q, $injector) {
...
//now get $http like this and use it as needed:
$injector.get('$http')

How to fail a successful Angular JS $http.get() promise

How do I reject or fail a successful $http.get() promise? When I receive the data, I run a validator against it and if the data doesn't have required properties I want to reject the request. I know I can do after the promise is resolved, but it seems like a good idea to intercept errors as soon as possible.
I'm familiar with the benefits of $q, but really want to continue using $http.
You can reject any promise by returning $q.reject("reason") to the next chained .then.
Same with $http, which returns a promise - this could be as follows:
return $http.get("data.json").then(function(response){
if (response.data === "something I don't like") {
return $q.reject("bad data");
}
return response.data;
}
This could simply be done within a service, which pre-handles the response with the .then as specified above, and returns some data - or a rejection.
If you want to do this at an app-level, you could use $http interceptors - this is just a service that provides functions to handle $http requests and responses, and allows you to intercept a response and return either a response - same or modified - or a promise of the response, including a rejection.
.factory("fooInterceptor", function($q){
return {
response: function(response){
if (response.data === "something I don't like") {
return $q.reject("bad data");
}
return response;
}
}
});
Same idea as above - except, at a different level.
Note, that to register an interceptor, you need to do this within a .config:
$httpProvider.interceptors.push("fooInterceptor");
You can use AngularJS interceptors. But you still need to use $q in them because $http uses $q.
Here is a useful article about interceptors.

AngularJS $http interceptors

Javascript code...
commonApp = angular.module('commonApp')
.config(function($httpProvider){
$httpProvider.interceptors.push('myHttpInterceptor');
})
.factory('myHttpInterceptor', function($q, $window){
return {
request: function(config){
console.log('Request started'); // LOG AT REQUEST START
return config || $q.when(config);
}
};
});
I believe that the message should be logged at the beginning of an xhr request.
But I am seeing logs without xhr requests.
Am I misunderstanding the api?
Your plunkr seems to be working fine? There's a good blog post on understanding angular http interceptors you might find useful: http://djds4rce.wordpress.com/2013/08/13/understanding-angular-http-interceptors/

Resources