24

Here is my HTML and JS File

HTML file

<!DOCTYPE html>
<html ng-app="">

<head>
  <!--Works with latest Stable Build-->
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>

  <!--Does not work with Latest Beta-->
  <!--UNCOMMENT ME! <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.18/angular.min.js"></script>-->


  <script src="script.js"></script>
</head>

<body ng-controller="MainController">
  <h1>Angular Playground</h1>
  {{message}}
  <br />Total Length: {{message.length}}
</body>

</html>

JAVASCRIPT FILE

var MainController = function($scope) {
    $scope.message = "Hello, Michael";
};

If I use the latest stable build, then I get the following result (which is obviously correct):

Angular Playground

Hello, Michael Total Length: 14

However, if I use Beta 18, then I get the following error:

Error: [ng:areq] Argument 'MainController' is not a function, got undefined

and the page returns the following:

Angular Playground #2

{{message}} Total Length: {{message.length}}

Any idea, what could be causing this?

mbcrump
  • 974
  • 3
  • 7
  • 15
  • Did you check this answer? Probably same issue? http://stackoverflow.com/questions/25111831/controller-not-a-function-got-undefined-while-defining-controllers-globally/25111942#25111942 – PSL Aug 19 '14 at 21:04
  • The above comment is the correct answer. I would vote on it if it was posted that way. – Chad Robinson Aug 19 '14 at 21:10

1 Answers1

60

With the latest versions of Angular (>1.3.0), you can't declare a global constructor function and use it with ng-controller.

A quick fix would be to create an angular module and add MainController as a controller.

Here I've wrapped MainController in an IIFE to prevent the function from being added as a global:

(function() {

    angular
        .module("appName", [])
        .controller("MainController", MainController);

    MainController.$inject = ["$scope"];

    function MainController($scope) {
        $scope.message = "Hello, Michael";
    };

})();

In your HTML, you'll need to add the name of the angular module to the ng-app directive:

<!DOCTYPE html>
<html ng-app="appName">

<head>
  <!--Works with latest Stable Build-->
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>

  <!--Does not work with Latest Beta-->
  <!--UNCOMMENT ME! <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.18/angular.min.js"></script>-->


  <script src="script.js"></script>
</head>

<body ng-controller="MainController">
  <h1>Angular Playground</h1>
  {{message}}
  <br />Total Length: {{message.length}}
</body>

</html>
SirTophamHatt
  • 1,581
  • 17
  • 23
  • 9
    Was about to throw a few punches until I saw this answer. The pluralsight Angular.js course uses an older version, where the global constructor was allowed. Had the exact same code (except forthe linked angular.js) and it just wouldn't work. This solved the problem. – mkvlrn Mar 05 '15 at 01:20
  • 2
    Took me a few mins to notice the subtlety of the ng-app="app" tag on the html that relates to angular.module("app", ... Thanks! – Opentuned Jul 06 '15 at 15:05