Dependency Injection in AngularJs

In this series, we have gone through many articles on AngularJs. This time I will discuss about Dependency Injection in AngularJs .

Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it possible to change them, whether at run-time or compile-time.

Before going to DI first we have to know about Service.

What is Service , factory or Provider in AngularJs?

They all are same, with different way of writing. This (Singleton design pattern) defines dependency between your controller and View through application.
We can Inject a service in Controller, which will watch over changes automatically and change its View as per required.

We have many inbuilt standard service available like $scope, $filter. All inbuilt services in AngularJS starts with this sign $. In same way we can create our own custom service and then inject in Controller.

Creating Custom Service :

var myApp = angular.module('myApp', []);

myApp.service('filteredListService', function() {
    this.retList = function(valLists){
        return valLists;
    }
});

We can create Service by calling “service“ method in module as shown above.

I have created service by name “filteredListService” , which simply returns array passed to it. Advantage of doing this is that whenever list changes in our application after searching or sorting, I have to simply call this method of service and remaining job of updating UI and other stuff will be handled by framework. I don’t have to write any code, That’s awesome 🙂

Passing Service in Controller:

Old definition of Controller was something like this in previous articles :

var TableCtrl = myApp.controller('TableCtrl', function ($scope) {
// ... code here
});

New Definition of controller to pass service will be:

var TableCtrl = myApp.controller('TableCtrl', function ($scope,filteredListService) {
// ... code here
});

As you can see, service name is passed as argument in controller. $scope is reserved keyword in AngularJs which represents Scope (link) between Controller and View.

Adding Service as DI

In order to inform AngularJs framework to add dependency between Service and our controller, we have to register it using below line of code :

TableCtrl.$inject = ['$scope', 'filteredListService'];

Difference between factory and Service?

If you define factory you will directly get value returned by method.

If you define Service, you will get reference of methods. I normaly prefer Service because it gives me flexibility to define many methods in single service and very easy to maintain code.

From Documentation:

Services
Syntax: module.service( ‘serviceName’, function );

Result: When declaring serviceName as an injectable argument you will be provided with an instance of the function. In other words new FunctionYouPassedToService().

Example :

var app = angular.module('myApp', []);

// Service definition
app.service('testService', function(){
    this.sayHello= function(text){
        return "Service says \"Hello " + text + "\"";
    };
});

// AngularJS Controller that uses the service
function HelloCtrl($scope, testService)
{
    $scope.fromService = testService.sayHello("World");
}

Factories
Syntax: module.factory( ‘factoryName’, function );

Result: When declaring factoryName as an injectable argument you will be provided with the value that is returned by invoking the function reference passed to module.factory.

Example :

var app = angular.module('myApp', []);

// Factory
app.factory('testFactory', function(){
    return {
        sayHello: function(text){
            return "Factory says \"Hello " + text + "\"";
        }
    }
});

// AngularJS Controller that uses the factory
function HelloCtrl($scope, testFactory)
{
    $scope.fromFactory = testFactory.sayHello("World");
}

Related posts