6

This AngularJS code works while located in the HTML file:

<!DOCTYPE html>
<html lang="en" ng-app="ChgReqApp">
    <head>
        <link rel="shortcut icon" href="IM/Coins.png" />
        <title>TITLE</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
        <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
        <!-- Change to min -->
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
        <script>
            angular.module('ChgReqApp', []);
            angular.module('ChgReqApp').controller('MainController', function ($scope) {
                $scope.ClientInfo = {};
                $scope.ChangeRequests = [];
            });
        </script>
        <script src="JS/MainController.js"></script>
    </head>
    <body ng-cloak ng-controller="MainController">
    </body>
</html>

The MainController.js file looks like this and the alert dialog works as expected:

// MainController.js
$(function () {

    alert("MainControllerFile");

});

Now, when I move the controller code to the MainController.js file, I get an error:

<!DOCTYPE html>
<html lang="en" ng-app="ChgReqApp">
    <head>
        <link rel="shortcut icon" href="IM/Coins.png" />
        <title>TITLE</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js">    </script>
        <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
        <!-- Change to min -->
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
        <script>
            angular.module('ChgReqApp', []);
        </script>
        <script src="JS/MainController.js"></script>
    </head>
    <body ng-cloak ng-controller="MainController">
    </body>
</html>

//MainController.js
$(function () {

    angular.module('ChgReqApp').controller('MainController', function ($scope) {
        $scope.ClientInfo = {};
        $scope.ChangeRequests = [];
    });

});

The error is:

Error: [ng:areq] Argument 'MainController' is not a function, got undefined
http://errors.angularjs.org/1.4.8/ng/areq?p0=MainController&p1=not%20a%20function%2C%20got%20undefined
    at ...

I have searched for a solution to this problem but all the discussions I have found relate to some other issue not applicable to the above code. The external js file is valid and the scripts are in the correct order. Any help on this is greatly appreciated.

3
  • 2
    Why did you add $(function () { }); around it when you moved it to a different file? Commented Jan 19, 2016 at 14:23
  • get rid of $(function(){}); Commented Jan 19, 2016 at 14:26
  • Thanks to you all. I had it outside of a jQuery function at one time and had some other error, but it must have been related to something else. Easy fix. I'm more experienced in strictly typed languages and getting my head around this is stretching me a bit. Commented Jan 19, 2016 at 14:57

4 Answers 4

3

There is no need for $(function() {}) because Angular has its own "Document Ready business" (just to simplify to the max :P).

The problem is that Angular can't run its "Document Ready Business" because you are putting Angular stuff inside jQuery's "Document Ready" shorthand and that stops the Angular framework from working properly.

You can read more about this in Angular's documentation

Angular initializes automatically upon DOMContentLoaded event or when the angular.js script is evaluated if at that time document.readyState is set to 'complete'. At this point Angular looks for the ng-app directive which designates your application root.

I think you can see how this conflicts with what you are trying to do.

Also as an additional suggestion go like this:

angular.module('ChgReqApp', []).controller('MainController', function($scope) {
    $scope.ClientInfo = {};
    $scope.ChangeRequests = [];
});

or like this (my preference)

var app = angular.module('ChgReqApp', []);
app.controller('MainController', function($scope) {
    $scope.ClientInfo = {};
    $scope.ChangeRequests = [];
});
Sign up to request clarification or add additional context in comments.

2 Comments

it's bad practice because your controller will be defined globally when your code will be compiled for production.
@senayar I agree with you especially if you are making modules for distribution you should wrap your stuff into a closure to avoid polluting the global scope. What I wrote is a personal preference. However, I have seen the styleguide you posted in your answer and will definitely have a look and take what I can to improve my knowledge :)
1
(function() {

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

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

    function MainController($scope) {
        $scope.ClientInfo = {};
        $scope.ChangeRequests = [];
    };

})();

you can read more information here : https://github.com/johnpapa/angular-styleguide

2 Comments

Thank you senayar. I will make use of the information in the styleguide. Question: What are the advantages of pulling out the controller function and injecting the $scope parameter?
If you don't use ng-annotate you need to inject all your dependencies otherwise during compilation you will have reference problems. It's like doing : app.controller('MainController', ['$scope, function($scope) { $scope.ClientInfo = {}; $scope.ChangeRequests = []; }]); You can read more about injection here : docs.angularjs.org/guide/di I recommend the use of ng-annotate.
0

This is what I found that FIXED my problem...

  • the CHROME browser was CACHING the (MainController.js)

  • I found this out by looking at (Chrome devtools, Network tab, MainController.js file, Response TAB) (* THE CODE WAS DIFFERENT *)

OPEN A NEW TAB in Chrome (fixed the cached MainController.js file)

I was having the same problem. I was just trying to put some VALUES in a MainController.js file EXTERNALLY.

<script src="./js/controllers/MainController.js"></script>

For some reason it wasn't working (from this file)...

But... when I tested directly from the HTML file (it worked)

    app.controller('MainController', ['$scope', function($scope) {
    // SCOPE
    $scope.test = "test(HTML FILE)";
    $scope.test2 = 'test2(HTML FILE)';
}]);

...but NOT IN THE EXTERNAL FILE?

DISABLE CACHE (CHROME)

  • open CHROME, (DevTools), Networks tab, CLICK (ON) (Disable Cache)

Comments

-1

try this

<!DOCTYPE html>
<html lang="en" ng-app="ChgReqApp">
    <head>
        <link rel="shortcut icon" href="IM/Coins.png" />
        <title>TITLE</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js">    </script>
        <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
        <!-- Change to min -->
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
        <script src="JS/MainController.js"></script>
    </head>
    <body ng-cloak ng-controller="MainController">
    </body>
</html>

//MainController.js

angular.module('ChgReqApp').controller('MainController', function ($scope) {
alert('in main controller');
            $scope.ClientInfo = {};
            $scope.ChangeRequests = [];
        });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.