de rigueur
de rigueur

Reputation: 61

AngularJS: Declaring vs Not declaring controller

I'm following the AngularJS tutorial on its site, and at the moment my controller is as followed, and the page loads perfectly:

var phonecatApp = angular.module('phonecatApp', []);
phonecatApp.controller('PhoneListCtrl', function($scope, $http) {
  $http.get('phones/phones.json').success(function(data) {
    $scope.phones = data;
  });

  $scope.orderProp = 'age';
});

As I was doing the "A Note on Minification" part of Step 5, I came up with this:

var phonecatApp = angular.module('phonecatApp', []);
function PhoneListCtrl($scope, $http) {
  $http.get('phones/phones.json').success(function(data) {
    $scope.phones = data;
  });

  $scope.orderProp = 'age';
}
//phonecatApp.controller('PhoneListCtrl', ['$scope', '$http', PhoneListCtrl]);

The page loads just fine with the second code, where I commented the creation of controller from the module. My question is, what's the difference between declaring a controller from the module and defining a function

Upvotes: 1

Views: 224

Answers (4)

user2638050
user2638050

Reputation:

There is no difference in the actual execution/behaviour, the second one is using something called a 'function constructor'. It is a common way of creating a class-like structure in javascript.

The first one under the hood will be doing the same thing it's just that angularJs' dependency injection model works with strings so this is easier to read.

Upvotes: 4

agconti
agconti

Reputation: 18103

Check out Todd Motto's style guide for angular: http://toddmotto.com/opinionated-angular-js-styleguide-for-teams/

Defining your controllers as a function expressions is important to keep your code DRY and allow for named stack traces:

This is okay:

function PhoneListCtrl($scope, $http) {
  $http.get('phones/phones.json').success(function(data) {
    $scope.phones = data;
  });

  $scope.orderProp = 'age';
}

The issue is that this puts the function in the global scope; ohhh nooo. The solution is to wrap the declaration in an IIFE. This allows you to keep the best practice of defining your functions and to not pollute the global scope.

Here's an example:

(function () {
  angular.module('app', []);

  // MainCtrl.js
  function MainCtrl () {

  }

  angular
    .module('app')
    .controller('MainCtrl', MainCtrl);

  // AnotherCtrl.js
  function AnotherCtrl () {

  }

  angular
    .module('app')
    .controller('AnotherCtrl', AnotherCtrl);

  // and so on...

})();

Upvotes: 1

Mik378
Mik378

Reputation: 22181

Like this:

function PhoneListCtrl($scope, $http) {

your function would be declared in the global scope.

And we know that is clearly bad to pollute the global scope since it may lead to variable/function conflict.

By wrapping it inside a controller, you isolate the scope.

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691765

Declaring a global function, AFAIK was possible in order to simplify simple demos and get up to speed quickly. In latest versions of Angular, it's not supported by default anymore (see https://github.com/angular/angular.js/commit/3f2232b5a181512fac23775b1df4a6ebda67d018).

It's bad practice anyway to pollute the global namespace with lots of functions.

Upvotes: 1

Related Questions