Purpose of Square Bracket use in angular

I would like to understand the difference between the declaration of MyOtherService and MyOtherComplexService. Especially what is the purpose of square bracket part? When to use them of not?

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

myapp.factory('MyService', function($rootScope, $timeout) {
    return {
        foo: function() {
        }
  }
});

myapp.factory('MyOtherService', function($rootScope, $timeout, MyService) {
    return {
        foo: function() {
      return "MyOtherService";
        }
  }
});

myapp.factory('MyOtherComplexService', ['$rootScope', '$timeout', 'MyService', function($rootScope, $timeout, MyService) {
    return {
        foo: function() {
      return "MyOtherComplexService";
        }
  } 
}]);

myapp.controller('MyController', function($scope, MyOtherService, MyOtherComplexService) {

  $scope.x = MyOtherService.foo();
  $scope.y = MyOtherComplexService.foo();

});

It enables AngularJS code to be minified. AngularJS uses parameter names to inject the values to your controller function. In JavaScript minification process, these parameters are renamed to shorter strings. By telling which parameters are injected to the function with a string array, AngularJS can still inject the right values when the parameters are renamed.

To add to Ufuk's answer:

ngmin - compiles your standard modules to min-safe modules

Angular's min-safe square bracket notation is cleary less convenient, because you have to type every dependency twice and argument order matters. There is a tool called ngmin which compiles your standard modules to min-safe modules, so you don't have to manage all those things by hand.

Angular + CoffeeScript

If you're using CoffeeScript the situation is even worse. You may choose between ngmin, which will destroy your source map, or if you want to write it out all by yourself you'll have to wrap your entire code with square brackets, which is super ugly.

angular.module('whatever').controller 'MyCtrl', ['$scope', '$http' , ($scope, $http) ->
  # wrapped code
]

In my opinion this is not a CoffeeScript flaw, but a poor design decision of the Angular team, because it's against all JS/CoffeeScript conventions not to have the function as the last argument. Enough ranting, here is a little helper function to work around it:

deps = (deps, fn) ->
  deps.push fn
  deps

This is a very simple function that accepts two arguments. The first one is an array of strings containing your dependencies, the second one is your module's function. You may use it like this:

angular.module('whatever').controller 'MyCtrl', deps ['$scope', '$http'] , ($scope, $http) ->
  # unwrapped code \o/

As of now, ng-min is deprecated. Use ng-annotate instead.

It is good practice to use ng-annotate in your build job so you don't have to deal with the min-safe / bracket notation when developing, as it makes the code harder to read and maintain.

There is a grunt-plugin and a gulp plugin available on npm.

Just to exemplify what was already said, if you use the following syntax:

myapp.factory('MyService', function($scope, $http, MyService) { ... });

most of the JS minifiers will change it to:

myapp.factory('MyService', function(a, b, c) { ... });

since functions argument names usually can be renamed for shorter names. This will break the Angular code.

In Angular, to get your code minifiable in all minifiers, you use the bracket syntax:

myapp.factory('MyService', ['$scope', '$http', 'MyService', function($scope, $http, MyService) { ... }]);

that will be minified to:

myapp.factory('MyService', ['$scope', '$http', 'MyService', function(a, b, c) { ... }]);

Note that minifiers do not touch on strings so Angular will see the minified code and match arguments in order:

$scope    = a
$http     = b
MyService = c

To avoid this ugly square bracket syntax, you should use smart minifiers like ng-annotate.