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.
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. As a developer our job is to pass the dependencies and AngularJS will inject them whenever the application needs them.
As a developer, we really don’t care about how AngularJS injects dependencies – we don’t need to know how the injection process works to develop applications. However, it is better if we know different ways of passing dependencies. In AngularJS, dependencies can be passed in three possible ways. They are as follows:
- Passing a dependency as Function Arguments
- Passing a dependency as Array Arguments
- Passing a dependency using the $inject service
Let us explore these options one by one.
Passing a dependency as a Function Argument
Perhaps most of the time you pass 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 perfectly fine, 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
Perhaps 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.
- Using the Named function
- 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, 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 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: how to interject dependencies in AngularJS apps. I hope you find this post useful, and thanks for reading!