345

How and where is app.run() used? After module definition, after app.config() or after app.controller()?

I am adopting the BreezeJS Angular Q, which asks whether certain code can be run in the app.run() function.

Talha Awan
  • 4,573
  • 4
  • 25
  • 40
user3071284
  • 6,955
  • 6
  • 43
  • 57

2 Answers2

659

Here's the calling order:

  1. app.config()
  2. app.run()
  3. directive's compile functions (if they are found in the dom)
  4. app.controller()
  5. directive's link functions (again, if found)

Here's a simple demo where you can watch each one executing (and experiment if you'd like).

From Angular's module docs:

Run blocks - get executed after the injector is created and are used to kickstart the application. Only instances and constants can be injected into run blocks. This is to prevent further system configuration during application run time.

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.

One situation where run blocks are used is during authentications.

Ofer Zelig
  • 17,068
  • 9
  • 59
  • 93
KayakDave
  • 24,636
  • 3
  • 65
  • 68
  • 4
    @KayakDave I'm not sure if this is off topic but in relation to the run order you mentioned above, when would Services be initiated and when would they be run? – jonnie Jul 28 '14 at 09:47
  • 3
    It's probably a little bit late to help you @jonnieM, but services will be executed depending upon when they're needed first - i.e. if you first need a service in a run block, it will execute immediately before that block. As for providers, annoyingly, they will run either before or after config blocks - depending on which order they come in the code. Considering that the only time you directly use a provider is at the config stage, this doesn't seem right. – Zac Seth Sep 26 '14 at 16:21
  • 3
    hi, i've forked and modified your fiddle sample to show also factory load: https://jsfiddle.net/lorezz/4cxgpLqj/1 – Lorezz Feb 16 '15 at 16:26
  • 1
    Awesome. To be thorough, app.constant() functions get invoked before everything... And app.factory() and other service functions get invoked "lazily." In other words, Angular uses the provided functions to create a service instance only when a controller or another service needs it injected, even if that's long after the app has been initialized. – Niko Bellic Sep 16 '15 at 03:55
  • In an Ionic project, by default run is called before config. Why is that ? – Rayjax Sep 20 '15 at 10:04
  • app.run() seems to be running more than one time wen the application kicks off though. This results in certain functions and alert statements being called more than once which is a little dirty. Why is this the case? – mesllo Jul 12 '16 at 12:29
  • I realized that if you listen a broadcast from the run method, the content executed is after controller load, and during rootScope digest, which means that you can't update app data from an event on run. Which is really annoying, because is a perfect place to instantiate the current user. – Pablo Ezequiel Leone Jan 15 '17 at 02:33
  • Under what situation would bootstrapping happen successfully and there are no errors but config still doesn't run? – rasharasha Jan 26 '17 at 18:09
  • could you add in the domain of app.run function? I know it's variadic but overall it's not obvious what inputs it expects if you are coming back to angular. – Dmytro Jan 23 '18 at 02:33
30

Specifically...

How and where is app.run() used? After module definition or after app.config(), after app.controller()?

Where:

In your package.js E.g. /packages/dashboard/public/controllers/dashboard.js

How:

Make it look like this

var app = angular.module('mean.dashboard', ['ui.bootstrap']);

app.controller('DashboardController', ['$scope', 'Global', 'Dashboard',
    function($scope, Global, Dashboard) {
        $scope.global = Global;
        $scope.package = {
            name: 'dashboard'
        };
        // ...
    }
]);

app.run(function(editableOptions) {
    editableOptions.theme = 'bs3'; // bootstrap3 theme. Can be also 'bs2', 'default'
});
Community
  • 1
  • 1
Michael Cole
  • 15,473
  • 7
  • 79
  • 96