$httpInterceptor not triggering before bootstrapping - angularjs

Currect Structure
I'm Bootstrapping my angular application manually because I have to get some data before booting my angular app, which uses $http & injected it manually using:
var initInjector = angular.injector(['ng']);
var $http = initInjector.get('$http');
& use $http to call api
I also have an http interceptor which uses $httpProvider to handle specific errors in app.config function.
$httpProvider.interceptors.push('HttpInterceptor');
The Problem
Consider the api call before bootstrapping, the http interceptor handling is not working. I think because the factory i'm passing the $httpProvider is not yet tied up & will be initialised after the bootstrapping is done.
So Tell Me
Should I handle error case manually for that particular http request(before bootstrapping) which I think would be redundant or Is there a way I can make tie the httpInterceptor work before bootstrapping.
What would be a better approach?

Related

Difference between xmlhttp (js) and $http (AngularJS)

In normal JavaScript we use xmlhttp for Ajax. Angular is providing ajax service using $http. Is there anything extra things in $http compare to xmlhttp?
$http in AngularJS cannot be configured to be synchronous while xmlhttp can do either synchronous or asynchronous. In AngularJS world, we use $http because it is the "Angular way" of doing requests.

Difference between dependency injection by passing argument and by using angular.injector

I had a use-case where I wanted to make the session timeout of the application configurable by making a call to REST api and get the value using $http. But as I found in this link how to inject dependency into module.config(configFn) in angular that services cannot be injected in config method, I have found this solution to make this work in the config:
var $http = angular.injector(['ng']).get('$http');
This is working fine, what is the difference between the two approaches and why this is working ? Also is there any limitation of using this approach.
angular.injector creates a new injector (application instance). It is misused most times and rarely ever needed in production.
It will have its own $http, $rootScope, $q, etc instances:
angular.injector(['ng']).get('$http') !== angular.injector(['ng']).get('$http');
The use of angular.injector in config block is an antipattern. It will result in untestable and potentially buggy code. $http request is asynchronous, application initialization will be completed first and likely result in race condition.
Most times when a need for $http in config appears, it should be performed in route resolver. If the response contains information that should be used to configure service providers and should be available in config block, it should be fetched prior to application bootstrap - in fact, there should be two applications, as shown here.

What is the difference between $http and $resource?

Can I use either for a REST call ? Or is there some minor difference ? I have used both of them in my projects with no side effects,
These are the main differences between $http and $resource:
$http:
$http is for universal purpose. It is an Ajax call.
$http is built into the AngularJS framework.
$http is good for quick retrieval.
$http is injected directly into an AngularJS controller by the developer.
For more details about $http refer: https://docs.angularjs.org/api/ng/service/$http
$resource:
$resource wraps $http to use in RESTful web APIs.
$resource needs to add the module separately.
$resource is good for conditions slightly more complex than $http.
$resource does not allow us to do much with data once it is consumed in the application. It is in the final state when it is delivered to the HTML DOM. The data are the same that the $http method will receive.
For more details about $resource refer: https://docs.angularjs.org/api/ngResource/service/$resource
You can find more answer here and here.

AngularJs console.log "$q is not defined"

I am getting this error in the console $q is not defined. When I did some research I found some thing like .q library has been deprecated from
http://www.breezejs.com/documentation/breeze-labs/breezeangularqjs
If this is so, then the whole concept of promises is also deprecated,
Promises are not deprecated. In fact they're gaining quite a lot of momentum lately and are included in the next version of JavaScript.
Let's look at what they say:
This breeze.angular.q library has been deprecated. It is superseded by the Breeze Angular Service which more cleanly configures breeze for Angular development.
The Breeze Angular Service tells Breeze to use Angular's $q for promises and to use Angular's $http for ajax calls.
What they say is that breeze uses Angular's own promises for promises rather than its own breeze.angular.q which uses Q promises which are more able but also much heavier than $q promises which Angular uses. This is simply an API change.
Inside Angular code, you can obtain $q using dependency injection - for example with the simple syntax:
myApp.controller("MyCtrl",function($q){
//$q is available here
});
Alternatively, if you want to use it independently you can use service location and obtain $q directly from an injector, but that's rarely the case. (If you want an example - let me know, I'd just rather not include code that's usually indicative of bad practice).
# in your console, try following code
$injector = angular.injector(['ng']);
q = $injector.get('$q');
deferred = q.defer();
# then do whatever you want

What is the best/easiest way to redefine a built-in angular service?

In our app, we are making cross domain requests, and so we have to use CORS. Since IE does this in a non-standard way, we created our own service (which has a dependency on $http for non-IE requests) that would handle all this for us. This all works fine within this app. However we have some non-app specific library code that needs to make requests. So, if these services in our library code simply use $http, the requests would not work in the app that needs to do CORS. However, we don't want these services injecting our CORS service, because that would break requests in apps that aren't doing cross-domain requests.
With all that being said, my end goal is to have the library code inject and use $http for all necessary requests. Then, in the specific apps, it could define how $http works. I initially thought I could just redefine the provider for $http. Something like this:
angular.module("myCorsApp").provider("$http", function() {
return {
$get: function(CORShttpService) {
return CORShttpService;
}
}
});
However, this results in the following error:
Circular dependency: CORShttpService <- $http <- $compile
I'm not sure I understand where the circular dependency is coming from. Does $compile have a dependency on the providers or something?
My real question is if I'm even going about this the right way. If there wasn't the circular dependency, I would think this would accomplish exactly what I want. Is there some workaround I can do to make this work? Is there a better/more correct way of doing this?
If it helps at all, the CORShttpService has the following dependencies: $q, $rootScope, $http, $timeout. Thanks for any help.
After digging around a bunch in the Angular docs, I decided that the best approach here was to "decorate" the $http service. This done with the decorator function of the $provide service. So, I ended up with something like this:
angular.module("myCorsApp").config(function($provide) {
$provide.decorator("$http", ["$delegate", "$q", "$rootScope", "$timeout", function($http, $q, $rootScope, $timeout) {
return function(requestConfig) {
//CORS logic using $http (basically what was the CORShttpService)
}
}]);
});

Resources