AngularJS Dependency Injection

Learn how AngularJS's injector automatically supplies dependencies like $scope, $http, and custom services to your controllers and services by matching parameter names.

What Is Dependency Injection?

Dependency injection means a controller or service does not create the objects it depends on - it simply declares what it needs, as parameters, and AngularJS's built-in injector supplies matching instances at runtime. This keeps components decoupled from how their dependencies are built and makes them far easier to test in isolation.

Example

<!DOCTYPE html>
<html>
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>

<script>
angular.module('diApp', [])
  .controller('UserController', function($scope, $http) {
    $http.get('/api/users').then(function(response) {
      $scope.users = response.data;
    });
  });
</script>

</body>
</html>

How the Injector Matches Parameter Names

When AngularJS instantiates a controller or service, it inspects the names of the function's parameters and looks up a registered provider for each matching name - $scope and $http above are both built-in services the injector recognizes automatically. This name-matching works fine in development, but JavaScript minifiers rename parameters, which breaks the match. The fix is the array-string annotation syntax, which pairs each dependency's string name with the function explicitly.

Example

<!DOCTYPE html>
<html>
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>

<script>
angular.module('diApp', [])
  .controller('UserController', ['$scope', '$http', function($scope, $http) {
    $http.get('/api/users').then(function(response) {
      $scope.users = response.data;
    });
  }]);
</script>

</body>
</html>
ServicePurpose
$scopeThe glue between a controller and its view; holds data and methods the template can bind to
$httpMakes AJAX requests to a backend API and returns promises
$timeoutAngularJS-aware wrapper around setTimeout that triggers a digest cycle when it resolves
$qCreates and composes promises
$locationReads and updates the browser's URL
$filterGives programmatic access to filters like currency or orderBy from JavaScript code

Creating and Injecting Custom Services

The injector is not limited to AngularJS's built-in services. Registering a service with angular.module(...).factory('Name', fn) adds 'Name' to the injector's registry, and from then on any controller or service can request it simply by naming it as a parameter - exactly the same mechanism used for $scope and $http.

Example

<!DOCTYPE html>
<html>
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>

<script>
angular.module('diApp', [])
  .factory('DataService', ['$http', function($http) {
    return {
      getProducts: function() {
        return $http.get('/api/products').then(function(res) {
          return res.data;
        });
      }
    };
  }])
  .controller('ProductController', ['DataService', function(DataService) {
    var vm = this;
    DataService.getProducts().then(function(products) {
      vm.products = products;
    });
  }]);
</script>

</body>
</html>
  • `.factory('Name', fn)` - fn's return value becomes the injectable object; the most common way to register a service.
  • `.service('Name', Constructor)` - AngularJS instantiates the constructor with `new`; useful when you prefer a class-like style.
  • `.provider('Name', fn)` - the most configurable form, allowing setup during the module's config phase; factory and service are both built on top of provider.
Note: Always list dependencies with the array-string syntax (or use a build tool like ng-annotate) before shipping to production. Minifiers rename function parameters, and without the string hints the injector can no longer match minified names to registered services.

Exercise: AngularJS Dependency Injection

How does a controller typically gain access to a service like $http?