15

I'm playing with AngularJS, but I'm getting an error message: Argument 'Controller' is not a function, got undefined Here's the JSFiddle, and HTML code:

<h2>Hata's Tree-Like Set</h2>
<div ng-app ng-init="N=3;" ng-controller="Controller">
<input type="range" min="1" max="10" step="1" ng-model="N">  
<div class="tree"></div>
</div

Then I define the Controller function in JavaScript, which is not registering for some reason.

function Controller($scope){
$scope.$watch("N", function(){  ... });}
john mangual
  • 7,718
  • 13
  • 56
  • 95

10 Answers10

12

I had exactly the same error: argument 'HelloCtrl' is not a function, got undefined.

Turns out I had a syntax error in my hello.js file... a missing comma in an array definition, inside HelloCtrl().

I added the comma, and then everything started working!

Hope this helps.

hkf
  • 4,440
  • 1
  • 30
  • 44
Deb Vorndran
  • 129
  • 1
  • 2
  • 4
    it doesn't, we don't know where the comma is supposed to go. please give an example – Matthew James Davis Dec 27 '13 at 22:00
  • 5
    What he is saying is "it could be anywhere, and nothing, not even the browser console, is going to tell you where". You just have to go over your coed with fine toothed comb. It helps if you can remember whet you changed last, or have a backup version which you can compare with. I get this error fairly often and for me it has always been caused by mis-matched brackets. YMMV. – Mawg says reinstate Monica Apr 30 '14 at 02:04
  • For what it's worth, I just tracked down my latest such error to array problem. I had to comment out a huge block of code written last midnight & uncomment it bit by bit. I had `myData.push(val: i);` instead of `$scope.myData.push({val: i});`` - mssing `$scope` and missing braces. Naturally, this means that my controller is not a function ;-) There is just on easy way to to solve this error. – Mawg says reinstate Monica Apr 30 '14 at 02:21
7

I had the same error... argument 'RadioController' is not a function...

I had referenced the Controller wrong in the HTML. I had

data-ng-controller="RadioController"

when it should have been

 data-ng-controller="Radio.RadioController"

('Radio' is the module the Controller was in)

user3214545
  • 2,103
  • 3
  • 20
  • 26
5

In the option of your fiddle, you choose to execute your javasctipt onLoad. With the onLoadoption your javascript is added on the window.onLoadfunction :

    window.onload=function(){
       function Controller($scope){
          ...
       }
    }

So angular can not access to your code because it is in a closure.

With the no wrapoption, your code is directly added in the page and is accessible to angular : JSFiddle.

You can browse the source to see how it works.

Bastien Caudan
  • 4,482
  • 1
  • 17
  • 29
  • the slider is supposed to control the complexity of the twig, basically the value `N` in a for loop – john mangual Mar 31 '13 at 22:31
  • Please explain the `no wrap` option you mention. This answer is missing some context that makes it less useful than it could be. – David Rivers Apr 10 '13 at 15:14
  • 1
    just to clarify - the `no wrap` option is within jsfiddle, not angular (you can see it in the control bar on the left). Removing this removes the closure which is what causes the OPs issue. For more on closures: http://stackoverflow.com/questions/111102/how-do-javascript-closures-work – Stuart Burrows Jun 12 '13 at 13:07
4

You can define a controller and register it in one step:

angular.module('myModule').controller('MyCtrl', function($scope) {
  $scope.$watch ....
});

If you want the code to work correctly after it's been minified, you have to explicitly specify the dependency on $scope:

angular.module('myModule').controller('MyCtrl', ['$scope', function(s) { 
  // you can now name the $scope argument whatever you want
  ...
}]);
glebm
  • 20,282
  • 8
  • 51
  • 67
4

I was having a hard time with this as well. The cause of my problem was that I had an old version of Angular that didn't support the new as aliasing.

Make sure you have the latest version of Angular that supports as.

jjnguy
  • 136,852
  • 53
  • 295
  • 323
1

Have you configured your $controllerProvider correctly?

From the documentation:

Name of a constructor function registered with the current $controllerProvider or an expression that on the current scope evaluates to a constructor function.

The controller instance can be published into a scope property by specifying ng-controller="as propertyName".

If the current $controllerProvider is configured to use globals (via $controllerProvider.allowGlobals()), this may also be the name of a globally accessible constructor function (not recommended).

Dávid Horváth
  • 4,050
  • 1
  • 20
  • 34
1

Well, I succeeded in solving this error by downgrading to legacy angular JS (1.2.27).

The same syntax (you have used above) for defining controller and angular JS (1.3.2) is the combination which caused this error.

With angular (1.3.2), following syntax worked for me.

var app = angular.module('dummyApp', []);

app.controller('helloController', function($scope){
    <write statements here>
});
Gautam G
  • 494
  • 2
  • 6
  • 15
1

There is no need to downgrade to older versions. You can use both the as method or the angular.module method.

Also the order of loading your files has to be correct.

(Consider require js if you have a hard time remembering the order of loading your files)

Mahendra Singh
  • 298
  • 2
  • 9
0

I had to re-order the script tags. I put the controller higher than another it depends on.

Took me a few hours, hope this helps someone else

Dan Power
  • 1,141
  • 1
  • 12
  • 18
0

I had this error - I'd got the case wrong in the name of my Controller.

It was registered as CallbacksController... took me five minutes of swearing to spot the case difference (hint - capital B in my case!).

cheesey_toastie
  • 401
  • 3
  • 7