Different Ways of Injecting Dependency in an AngularJS Application

Dhananjay Kumar / Saturday, February 27, 2016

When you start learning the very first characteristics of AngularJS, you may come across something called Dependency Injection (DI): the premise that AngularJS injects dependencies whenever an application needs them. As a developer, our task is only to pass the dependency to the module and everything else will be taken care by AngularJS. Now I can show you how it's all done in an easy way using one of the best Angular Component Libraries on the market - Ignite UI for Angular.

To create a controller, we pass $scope object and other dependencies to the module’s controller function. For example, to create a ProductController, we are passing $scope object and Calculator service dependencies. This reiterates the knowledge that, as a developer, our job is to pass the dependencies and AngularJS will inject them whenever the application needs them.

From our standpoint, we really don’t care about how AngularJS injects dependencies – we don’t need to know how the injection process works to develop applications. It is, however, better if we know a variety of ways for passing dependencies. In AngularJS, dependencies can be passed in three possible ways. They are as follows:

  1. Passing a dependency as Function Arguments
  2. Passing a dependency as Array Arguments
  3. Passing a dependency using the $inject service

Let us explore these options one by one.

 Passing a dependency as a Function Argument

Perhaps you find yourself frequently passing a dependency as a function argument, which is perfectly fine. For example, we pass a $scope object to create a controller as shown in the listing below:

app.controller("ProductController", function ($scope) {

    $scope.message = "Hey I am passed as function argument"

});

Passing dependencies as function arguments works well until we deploy the application in the production with a minified version of the application. Usually, to improve the performance, we minify the application in production, but passing the dependency as a function argument breaks when we minify the application.

Obviously in production, for better performance, we would like to deploy the minified version of the application, but the application will break because the parameter name will change to a shorter alias name. To avoid this break in production, we should choose another option.

Passing a dependency as Array Arguments

Possibly the most popular way of passing a dependency in an AngularJS application is passing them as Array Arguments. When we pass a dependency as an Array Argument, the application does not break in production when we minify the application. We can do this in two possible ways:

  1. Using the Named function
  2. Using the Inline Anonymous function

Using the Named function

We can pass dependencies as Array Arguments with the named function as shown in the listing below:

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

function ProductController($scope) {
    $scope.greet = "Infragistics";
};
app.controller('ProductController', ['$scope', ProductController]);

As you’ll notice, we are passing a dependency $scope object in the array along with the name of the controller function. More than one dependency can be passed, as long as they are separated by a comma. For example, we can pass both $http service and the $scope object as dependencies as shown in the listing below:

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

function ProductController($scope,$http) {
    $scope.greet = $http.get("api.com");
    
    
};
app.controller('ProductController', ['$scope','$http', ProductController]);

As we discussed earlier, passing dependencies as Array Arguments does not break application when we minify the application.

Using the Inline Anonymous function

Personally, I find using a named function much more convenient than using an inline anonymous function. For me, it’s easy to manage the named controller function. If you prefer the inline function, you can pass dependencies as array arguments exactly the same way you pass them in named controller functions. We can pass dependencies in an inline function as array arguments, as shown in the listing below:

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

app.controller('ProductController', ['$scope', '$http', function ($scope,$http) {

    $scope.greet = "Foo is Great!"
}]);

Keep in mind that dependencies injected as Array arguments work even if we minify the application.

Passing a dependency using the $inject service

There is one more way to inject dependencies in AngularJS: by using the $inject service. In doing so, we manually inject the dependencies. We can inject $scope object dependencies using the $inject service as shown in the listing below:

function ProductController($scope){
    $scope.greet = "Foo is Not Great!5";
}

ProductController.$inject = ['$scope'];

app.controller('ProductController', ProductController);

Using the $inject service also does not break the application when we minify the application for production. Most often we will find $inject services being used to inject dependencies in unit testing of the controller.

Before we end this article, let us see how we can use $inject to inject a service to the controller in a real-time application. We have created a service as shown in the listing below:

app.factory("Calculator", function () {

    return {
        add: function (a, b) {
            return a + b;
        }
    }
});

We need to use a Calculator service inside CalController. The CalController can be created as shown in the listing below:

app.controller('CalController', CalController);
function CalController($scope, Calculator) {

    $scope.result = 0;
    $scope.add = function () {
        alert("hi22");
        $scope.result= Calculator.add($scope.num1, $scope.num2);
    }
};

At this point, the application should work because dependencies are passed as function arguments. However, the application will break when we minify it. So let us go ahead and inject the dependencies using the $inject as shown in the listing below:

CalController.$inject = ['$scope', 'Calculator'];

On the view, the controller can be used as shown below:

<div ng-controller="CalController">
        <input type="number" ng-model="num1" placeholder="Enter number 1" />
        <input type="number" ng-model="num2" placeholder="Enter number 2" />
        <button ng-click="add()">Add</button>
        {{result}}
    </div>

And there you have it - the easiest way to interject dependencies in AngularJS apps.

Ignite UI for Angular library