Angular Dependency Injection

Angular Module Loading

Angular modules have the opportunity to configure themselves before the module actually bootstraps and starts to run.

 

 

Configuration Block

This phase is the only part of the Angular flow that can be modified before the app starts up.

 

The only services that can be injected in this block are constants and providers;

angular
    .module('myApp', [])
    .config(['provider', 'constant', function(provider, constant){
        //Configuration logic
    }]);

Run Block

  • Executed at begining of the application;
  • Similar with the main() method in other programming languages;
  • Any service can be injected here.
angular
    .module('myApp', [])
    .config(function(){})
    .run(['$rootScope', function($rootScope){
        $rootScope.globalValue = 'Global Foo';
    });

Angular Services

  • singleton objects that are instantiated only once per application;
  • lazy-loaded (created only when necessary);
  • provide a way to share data and behavior across controllers, directives, filters or other services;

How to create a service?

  • .constant();
  • .value();
  • .service();
  • .factory();
  • .provider();

Constant

  • used for registering a constant service such as string, number, array, object or function;
  • can not have any dependency;
  • can not be overridden by an Angular decorator;

Constant Example

angular
    .module('myApp', [])
    .constant('apiUrl', 'http://localhost:8080')
    .config(['apiUrl', function(apiUrl){
        //apiUrl can be used here
    }])
    .run(['$rootScope', function($rootScope){
        //apiUrl can be used here
     }]);

Value

  • used for registering a value service such as string, number, array, object or function;
  • can't have any dependency;
  • can be overridden by an Angular decorator;

Value Example

angular
    .module('myApp', [])
    .value('objectValue', {
        foo: 'bar',
        setFoo: function(val){
            this.foo = val;
        }
    })
    .config(function(){
        //objectValue can not be injected here
    })
    .run(['$rootScope', 'objectValue',
        function($rootScope, objectValue){          
            $rootScope.foo = objectValue.foo;
            $rootScope.changeFoo = function(val){
                objectValue.setFoo(val);
            };
        }
    ]);

Factory

  • used for registering a service factory wich will be called to return the service instance;
  • can have any dependency;
  • can be overridden by an Angular decorator;

Factory Example

angular
    .module('myApp', [])
    .factory('myFactory', function(){
        var data;  //private variable  

        return {
            fetchData: function(){
                //business to populate data
            },
            getData: function(){
                return data;
            }
        } 
    })
    .run(['$rootScope', 'myFactory',
        function($rootScope, myFactory){          
            myFactory.fetchData();
            $rootScope.data = myFactory.getData()    
        }
    ]);

Service

  • used for registering a service constructor wich will be invoked with new to create the service instance;
  • can have any dependency;
  • can be overridden by an Angular decorator;

Service Example

angular
    .module('myApp', [])
    .service('myService', function(){
        var data;  //private variable 
 
        this.fetchData= function(){
            //business to populate data
        };
        this.getData= function(){
            return data;
        };
    })
    //Same as
    .factory('myService', function(){
        var Service = function(){
            var data;  //private variable  
            this.fetchData= function(){
                //business to populate data
            };
            this.getData= function(){
                return data;
            };
        };

        return new Service();
    });

Provider

  • used for registering a provider function;
    • constructor functions, whose instance are responsible for 'providing' a factory for a service;
    • can have aditional methods that allow configuration of the provider or it's returning service;
    • must have a $get method that returns the factory service;
  • only the $get method can have any dependency;

Provider Example

angular
    .module('myApp', [])
    .provider('myFactory', function(){
        var configVar = 'value';
        //The factory Service - can have any dependency
        this.$get = [function(){
            var data;  //private variable 
            return{
                fetchData: function(){
                //business to populate data
                },
                getData: function(){
                    return data;
                }
            };
        }];
        //Config method
        this.config = function(config){
            configVar = config;
        };
    })
    .config(['myFactoryProvider', function(myFactoryProvider){
        myFactoryProvider.config('Overriden value');
    }])
    .run(['$rootScope', 'myFactory',
        function($rootScope, myFactory){          
            myFactory.fetchData();
            $rootScope.data = myFactory.getData()    
        }
    ]);

Angular internal services

  • Angular comes with several built-in services like:
    • $http;
    • $compile;
    • $provider;
    • much more.
  • The $ is a convention to point that the service comes from the framework and it's not custom-made;

Angular decorator

  • used for registering a service decorator;
  • intercepts the creation of a service, allowing it to override or modify the behavior of the service;
  • the object that is returned may be:
    • the originar service;
    • a new service object wich replaces the old one;
    • a new service wich wraps and delegate to the original service;

Decorator Example

angular
    .module('myApp', [])
    .factory('myFactory', function(){
        //implementation here
    })
    .config(['$provide', function($provide){
        $provide.decorator('myFactory', ['$delegate', function($delegate){
            //$delegate is the original service instance
            //add a new method
            $delegate.newMethod = function(){
                return 'This method was added by the decorator';
            };

            //return the original decorated method
            return $delegate;
        }]);
    }]);

Angular Routing

ngRoute

Layout Template

ngRoute module provides the ng-view directive, in order to render the routes template.

Any time the route is changed are taken the following actions:

  • the view will update;
    • if there is a template associated with the current route:
      • create a new scope - inherited from the parent;
      • remove the last view and clean the last scope;
      • link the new scope with the new tepmlate;
      • link the controller (if specified) with the scope;

Routes

To create routes on a specific module or app, ngRoute module exposes the $routeProvider.

 

To add a specific route, $routeProvider has the when() method.

$routeProvider
    .when('path', {
        template: 'Html string or a function that returns Html string',
        templateUrl: 'path or function that returns a path to an html template that should be used by ngView',
        controller: 'Controller fn that should be associated with newly created scope or the name of a registered controller if string',
        controllerAs: 'A controller alias name',
        resolve: 'An optional map of dependencies which should be injected into the controller',
        redirectTo: 'value to update the path with and trigger route redirection.' 
    })
    .otherwise(routeConfigObj);

Routes Example

angular
    .module('myApp', ['ngRoute'])
    .config(['$routeProvider', function($routeProvider){
        $routeProvider
            .when('/', {
                template: '<h2>{{page}}</h2>',
                controller: ['$scope', function($scope){
                    $scope.page = 'home';
                }]
            })
            .when('/about', {
                template: '<h2>{{page}}</h2>',
                controller: ['$scope', function($scope){
                    $scope.page = 'about';
                }]
            })
            .otherwise({redirectTo: '/'});
    }]);
<html ng-app="myApp">
<head>...</head>
<body>
    <header>
        <h1>My app</h1>
        <ul>
          <li><a href="#/">Home</a></li>
          <li><a href="#/about">About</a></li>
        </ul>
    </header>

    <div class="content">
        <div ng-view></div>
    </div>
</body>
</html>
    

Demo - Live Coding

Angular Dependency Injection

By Alexe Bogdan

Angular Dependency Injection

Angular Framework: Services and ngRoute

  • 993