aidan
aidan

Reputation: 9576

Defining basic AngularJS controllers with services

Reading through the documentation and playing with jsfiddle, I've noticed controllers being defined (and working) in the following ways*:

function InvoiceCntl( $scope ) {...}
function Ctrl2( $scope, $timeout ) {...}
function countController1( $scope, $http, $timeout ) {...}
function countController2( $scope, $timeout, $http ) {...}

My question is about the part of the AngularJS library that calls my controller: how does it know what services I'm expecting and which order my controller expects them in?

It's JavaScript, Jim, but not as we know it.

*bearing in mind that controllers shouldn't be defined in the global scope

Upvotes: 0

Views: 105

Answers (3)

jvandemo
jvandemo

Reputation: 13296

By default, the AngularJS injector service will match the names of the arguments of your controller function against the names of built-in AngularJS services (starting with $ sign):

// Old way to define your controller
angular.module('yourModule')
    .controller('yourController', function($scope, $http, yourService){

        // Your code here

    });

However, since this is simply based on string comparison, this can cause problems when your code is uglified and/or minified.

Therefore it is recommended that you use the newer syntax for creating controllers using the array notation like this:

// Newer, better way to define your controller
angular.module('yourModule')
    .controller('yourController', ['$scope', '$http', 'yourService', function($scope, $http, yourService){

        // Your code here

    }]);

Notice that the controller function is replaced by an array consisting of the services you would like to inject and ending with the controller function.

AngularJS will now inject the services in the order you specified them in the array like this:

['yourService', 'yourOtherService', function(yourService, yourOtherService){

    // You can use yourService and yourOtherService here
}]

The names don't have to correspond, so you can use:

['$http', '$scope', function(h, s){

    // You can use h and s here
    // h will be the $http service, s will be the $scope
}]

It's highly recommended to use the newer array notation because it guarantees that your code will still work after minifying or uglifying it.

Hope that helps!

Upvotes: 1

sakthi
sakthi

Reputation: 929

Controllers doesn't expect them to be in any order! They only identifies them with the Name of the services which can be in any order.

Upvotes: 0

Michael Benford
Michael Benford

Reputation: 14104

From Angular's dev guide:

How does the injector know what service needs to be injected?

(...)

Inferring Dependencies

The simplest way to get hold of the dependencies, is to assume that the function parameter names are the names of the dependencies.

function MyController($scope, greeter) { ... }

Given a function the injector can infer the names of the service to inject by examining the function declaration and extracting the parameter names. In the above example $scope, and greeter are two services which need to be injected into the function.

That doesn't remain true when your code needs to get minified. Check "$inject Annotation" section in the dev guide (link above) to better understand it.

Upvotes: 1

Related Questions