Angularjs suitable moment to launch a http request when app start - angularjs

I just started to learn Angularjs 2 days ago. A question have confused me for all the 2 days.
I need to make a http request to the server to get some data when the app start, but I cannot find the suitable moment to do this.
I've tried to make a controller, which calls $http.get(). But It doesn't work. It seems that the controller won't be instantiated if it's never used in the html (not sure about this).
I also tried to find other ways, but I only found $http which is used for http request. And $http only appears in the controller.
Maybe I need use other Angularjs methods? Or, I should do the instantiate action manually?

Something like:
angular.module('yourApp').run(['$rootScope', '$http', function ($rootScope, $http) {
// do stuff here
}]);
From the documentation:
Run Blocks
Run blocks are the closest thing in Angular to the main method. A run block is the code which needs to run to kickstart the application. It is executed after all of the service have been configured and the injector has been created. Run blocks typically contain code which is hard to unit-test, and for this reason should be declared in isolated modules, so that they can be ignored in the unit-tests.

Related

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.

Angular ngmock httpBackend - ignore all but one request?

I am new to writing unit tests, so apologies if this is a dumb question. If I'm trying to test a method in an Angular controller that relies on mock data from a service call, and I want to also mock that service call (ngResource), is there a way to make httpBackend ignore other requests made in my controller on initialization?
I've tried placing my whenGET or expectGET definitions in before blocks, and only instantiating my controller within my test, but I always find that httpBackend is expecting other requests (Error: Unexpected request) when I call flush(). I do not want to write mocks for all other requests, just the one I'm using for this test.
Of course, this may be a stupid idea, as I can also just provide the fake data directly, and not test the service along with the controller's method. I've verified that this works. Maybe the correct answer is that I shouldn't be testing services from within a controller.
FWIW, I've also tried using Sinon fakeServer, and apparently it doesn't even pick up on Angular's XHR implementation (the server never responds).

AngularJS Documentation of .run() function

I am working with angularJS routing. In this regard I need documentation of .run() function.What is the responsibility of .run() function.Thanks
From the docs
Run Blocks
Run blocks are the closest thing in Angular to the main method. A run
block is the code which needs to run to kickstart the application. It
is executed after all of the services have been configured and the
injector has been created. Run blocks typically contain code which is
hard to unit-test, and for this reason should be declared in isolated
modules, so that they can be ignored in the unit-tests.
run() is also the earliest you will have access to $rootScope. It is a good place to register states and routes.

Using $httpBackend to Make Synchronous Calls?

We are using a 3rd part i18n module for translations in my app. Specifically https://github.com/doshprompt/angular-localization
Problem
The issue we are having is that the locale service is needed before it can possibly be loaded. If it is needed in a state we can resolve locale on the state resolve but if a script has to run before any state is even requested there is a timing conflict.
In this example I'm trying to load a service that needs locale before locale is loaded or could possibly have enough time to load.
Example
angular.module('config', []).service('myService', ['ngLocalization', function(locale) {
return {
foo: locale.getString('bar')
}
}]);
angular.module('app', ['config']).run(['myService', function(myService) {
/// ... do stuff ...
}]);
I'm anti-mess
This may seem simple- just add locale.ready('common').then(function() {}); to the service. And that's something we COULD do.. EVERYWHERE (there are a lot of places). But we don't want to add this confusing mess to our code that is unstable. And we don't want to get into the habit of having every service, controller, directive, etc etc. checking that all the possible dependencies and their resources are loaded independently.
$httpBackend Solution?
$httpBackend is for unit testing but can it be used- or is there another service to use- to set the respond to an http request? And if there is already a response is it then synchronous? Then when the config module loads it makes a ready request for all needed lang files which get applied immediately and the timing conflicts will go away.
Thoughts?

.config, .run, AppCtrl - where to put routes?

I wanted to find out the difference between the .config and .run functions in AngularJS. I was using my .config for setting up routes, but I did have some $on's for watching route change start and success events.
I then moved some of this code to .run as I was having some dependency injection problems in .config.
I finally moved some of this to a CommonAppController which I have set on my <body>.
I also had 2 .config's and it seemed to be running ok, but surely this isn't right?
Can anyone give a little insight on which method to use?
Configuration blocks and run blocks get executed at different points in the application bootstrap, and have different injection locals at their disposal. Here's a summary of what you can find in the AngularJS documentation.
Configuration blocks (registered with module.config()) get executed during provider registration, and can only be injected providers and constants (see module.provider() and module.constant()). This is typically where you would configure application-wide stuff, such as the $routeProvider. Stuff that needs to be configured before the services are created.
Run blocks (registered with module.run()) get executed after the injector has all the providers. Now, all instances and constants can be injected. This is typically where you would configure services, $rootScope, events and so on.
You can have multiple of either, and they are executed in the order they were registered to the module. Some people prefer to register a configuration block before every group of controllers to register the routes to these controller, for example.
The .config block is executed during the provider registration and configuration phase. It' a module level block.
The.run block is executed after the config block. It's used to inject services and constants.

Resources