user3379651
user3379651

Reputation: 77

Priority and hierarchy of execution of services in angularjs

What is the priority of services in AngularJS and what is the order of their execution? Please explain the concepts below with examples: service, provider, factory, config, controller, constant, value and run
What will execute first, then second and so on.

Thanks in advance.

Upvotes: 4

Views: 1860

Answers (1)

Dan Mindru
Dan Mindru

Reputation: 6104

It's easy to see the hierarchy of execution by playing with console.log(). As you can see in this snippet, the execution order is:

  1. => Run
  2. => Factory
  3. => Service
  4. => Provider

Run gets executed after the injector is created and is used to kickstart the application. It's the closest thing to a main method in Angular.

The example contains other AngularJS components too, showing the order of execution in general. Check out the console for more details. The code below is the same as the one in JS Bin, maybe you'll find it more convenient to analyze it here.

angular.module('App', []);

/*
 * Configuration blocks - get executed during the provider registrations and configuration phase. Only providers and constants can be injected into configuration blocks. This is to prevent accidental instantiation of services before they have been fully configured.
 */
angular.module('App').config(function(){
  console.log('1. Config: You cannot inject $rootScope here');
});

/*
 * 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.
 */
angular.module('App').run(function($rootScope){
  console.log('2. Run: Close to a "main" method');
  $rootScope.counter = 1;
  $rootScope.components = [];
  $rootScope.components.push({
    'name': 'Run',
    'order': $rootScope.counter
  });
});

/*
 * Controller - the scope-augmenting constructor
 */
angular.module('App').controller('Ctrl', function($rootScope, Factory, Service, Provider) {
  console.log('7. Controller: Set up the initial state & add behavior to $scope');
  $rootScope.counter ++;
  $rootScope.components.push({
    'name': 'Controller',
    'order': $rootScope.counter
  });
});

/*
 * Directive - used to attach a specified behavior to a DOM element
 */
angular.module('App').directive('directive', function($rootScope) {
  console.log('3. Directive: Use to manipulate the DOM');
  $rootScope.counter ++;
  $rootScope.components.push({
    'name': 'Directive',
    'order': $rootScope.counter
  });
  
  return {
    controller: function() {
      console.log('* Directive controller');
    },
    compile: function(){
      console.log('* Directive compile');
      return {
        pre: function(){
          console.log('* Directive pre link');
        },
        post: function(){
          console.log('* Directive post link');
        }
       };
     }
   };  
});

/*
 * Filter - formats the value of an expression for display to the user.
 */
angular.module('App').filter('low', function($rootScope) {
  return function filterOutput(input) {
    console.log('8. Filter: Use to format a value');
    $rootScope.counter ++;
    $rootScope.components.push({
      'name': 'Filter',
      'order': $rootScope.counter
    });
    
    return input.toLowerCase();
  };
});

/*
 * Factory - the Factory recipe constructs a new service using a function with zero or more arguments
 */
angular.module('App').factory('Factory', function($rootScope) {
  console.log('4. Factory - before controller');
  $rootScope.counter ++;
  $rootScope.components.push({
    'name': 'Factory',
    'order': $rootScope.counter
  });
  return 'Factory';
});

/*
 * Service - the Service recipe produces a service just like the Value or Factory recipes, but it does so by invoking a constructor with the new operator.
 */
angular.module('App').factory('Service', function($rootScope) {
  console.log('5. Service - before controller');
  $rootScope.counter ++;
  $rootScope.components.push({
    'name': 'Service',
    'order': $rootScope.counter
  });
  return 'Service';
});

/*
 * Provider - the Provider recipe is the core recipe type and all the other recipe types are just syntactic sugar on top of it.
 */
angular.module('App').factory('Provider', function($rootScope) {
  console.log('6. Provider - before controller');
  $rootScope.counter ++;
  $rootScope.components.push({
    'name': 'Provider',
    'order': $rootScope.counter
  });
  return 'Provider';
});
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"/>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.js"></script>

<section ng-app="App" ng-controller="Ctrl" class="jumbotron">
  <ul directive>
     <li ng-repeat="item in components | orderBy:'order'">
       <b>{{item.order}}</b> => {{item.name}}
     </li>
  </ul>

  <p>A quick overview of {{'ANGULAR FLOW' | low}}.</p>
</section>

Upvotes: 2

Related Questions