[javascript] Controller not a function, got undefined, while defining controllers globally

I am writing a sample application using angularjs. i got an error mentioned below on chrome browser.

Error is

Error: [ng:areq] http://errors.angularjs.org/1.3.0-beta.17/ng/areq?p0=ContactController&p1=not%20a%20function%2C%20got%20undefined

Which renders as

Argument 'ContactController' is not a function, got undefined

Code

<!DOCTYPE html>
<html ng-app>
<head>
    <script src="../angular.min.js"></script>
    <script type="text/javascript">
        function ContactController($scope) {
            $scope.contacts = ["[email protected]", "[email protected]"];

            $scope.add = function() {
                $scope.contacts.push($scope.newcontact);
                $scope.newcontact = "";                 
            };
        }    
    </script>    
</head>

<body>    
    <h1>  modules sample </h1>

    <div ng-controller="ContactController">
        Email:<input type="text" ng-model="newcontact">
        <button ng-click="add()">Add</button>

        <h2> Contacts </h2>
        <ul>
            <li ng-repeat="contact in contacts"> {{contact}} </li>
        </ul>    
    </div>
</body> 
</html>

The answer is


With Angular 1.3+ you can no longer use global controller declaration on the global scope (Without explicit registration). You would need to register the controller using module.controller syntax.

Example:-

angular.module('app', [])
    .controller('ContactController', ['$scope', function ContactController($scope) {
        $scope.contacts = ["[email protected]", "[email protected]"];

        $scope.add = function() {
            $scope.contacts.push($scope.newcontact);
            $scope.newcontact = "";

        };
    }]);

or

function ContactController($scope) {
    $scope.contacts = ["[email protected]", "[email protected]"];

    $scope.add = function() {
        $scope.contacts.push($scope.newcontact);
        $scope.newcontact = "";
    };
}
ContactController.$inject = ['$scope'];
angular.module('app', []).controller('ContactController', ContactController);

It is a breaking change but it can be turned off to use globals by using allowGlobals.

Example:-

angular.module('app')
    .config(['$controllerProvider', function($controllerProvider) {
        $controllerProvider.allowGlobals();
    }]);

Here is the comment from Angular source:-

  • check if a controller with given name is registered via $controllerProvider
  • check if evaluating the string on the current scope returns a constructor
  • if $controllerProvider#allowGlobals, check window[constructor] on the global window object (not recommended)
 .....

expression = controllers.hasOwnProperty(constructor)
            ? controllers[constructor]
            : getter(locals.$scope, constructor, true) ||
                (globals ? getter($window, constructor, true) : undefined);

Some additional checks:-

  • Do Make sure to put the appname in ng-app directive on your angular root element (eg:- html) as well. Example:- ng-app="myApp"

  • If everything is fine and you are still getting the issue do remember to make sure you have the right file included in the scripts.

  • You have not defined the same module twice in different places which results in any entities defined previously on the same module to be cleared out, Example angular.module('app',[]).controller(.. and again in another place angular.module('app',[]).service(.. (with both the scripts included of course) can cause the previously registered controller on the module app to be cleared out with the second recreation of module.


Similar questions with javascript tag:

Similar questions with angularjs tag:

Similar questions with angularjs-directive tag:

Similar questions with angularjs-scope tag: