0

At some point this afternoon I suddenly got the following AngularJS error: Argument 'MainCtrl' is not a function, got undefined

I have a good version still running in Chrome without any errors, so I'm attempting to find the diffs - however to no avail.

I would appreciate any advice on how to fix the error Argument 'MainCtrl' is not a function, got undefined

I load the controllers.js file in index.html - within the body section:

 <!DOCTYPE html>
 <html ng-app="rage.ui">

 <head>
     <!-- loading css files here... -->
 </head>

 <body ng-controller="MainCtrl as main">

  <!-- Wrapper-->
  <div id="wrapper">
     <!-- Navigation -->
  </div>

  <script src="app/app.js"></script>
  <script src="app/config.js"></script>
  <script src="app/js/controllers.js"></script>

</body>

Here's the MainCtrl in my controllers.js file (also loaded in index.html) -

* MainCtrl - controller */

(function () {
 'use strict';
 angular.module('rage.ui')
    .controller('MainCtrl', ['$scope', '$interval', '$window', 'widgetDefinitions', main])
    .factory('widgetDefinitions', [widgetDefinitions])
    .value('defaultWidgets', [
    { name: 'random' },
    { name: 'time' },
    { name: 'datamodel' },
    {
        name: 'random',
        style: {
            width: '50%'
        }
    },
    {
        name: 'time',
        style: {
            width: '50%'
        }
    }
    ]);

function main($scope, $interval, $window, widgetDefinitions, defaultWidgets) {
    this.userName = 'Risk user';
    // ...
}
  function widgetDefinitions(RandomDataModel) {
    return [
      {
          name: 'random',
          directive: 'wt-scope-watch',
          attrs: {
              value: 'randomValue'
          }
      }
      {
          name: 'treegrid',
          templateUrl: 'app/views/templateGadget/treeGrid.html',
          title: "Tree Grid Report",
          attrs: {
              width: '50%',
              height: '250px'
          }
      }
    ];
  }

})();

in my attempt to add a new 'gadgetModelFactory' to the malhar Angular-Dashboard framework, I broke my system. Here's the good version of my new factory, now fixed:

'use strict';

angular.module('rage').
factory('gadgetDataModel', function ($scope, WidgetDataModel) {
function gadgetDataModel() {
    var test = 123;
}

gadgetDataModel.prototype = Object.create(WidgetDataModel.prototype);
gadgetDataModel.prototype.constructor = WidgetDataModel;

angular.extend(gadgetDataModel.prototype = {        
    init: function () {
        // to be overridden by subclasses
        var dataModelOptions = this.dataModelOptions;
    },

    destroy: function () {
        // to be overridden by subclasses
        WidgetDataModel.prototype.destroy.call(this);
        $interval.cancel(this.intervalPromise);
    }
});

});

and my app.config:

(function () {
angular.module('rage.ui', [
    'ui.router',
    'ui.bootstrap',
    'ui.dashboard'
])
})();
bob.mazzo
  • 4,419
  • 15
  • 65
  • 135
  • Where is ng-app in your view? – PSL Dec 13 '14 at 00:01
  • @PSL - I was trying to keep the code short and concise so I inadvertently left out ng-app. Please see my revised index.html, as well as my app.js – bob.mazzo Dec 13 '14 at 00:05
  • 1
    Change main to be vm so MainCtrl as vm, because your alias and your function can't the same. – Omar.Alani Dec 13 '14 at 00:08
  • 1
    @bob Don't see any issue with the code you have provided. http://plnkr.co/edit/Y2kHhOclaKJVCZmiwHHA?p=preview Do you see any other error in the console? Are you sure your controller file is loaded? – PSL Dec 13 '14 at 00:09
  • @Omar.Alani function name and alias cannot be same? He is not using global controller.. It is controller As syntax and also controller is registered, it has nothing to do with the controller constructor. Also "vm" what a horrible alias.. :( – PSL Dec 13 '14 at 00:13
  • @PSL - yes controllers.js is loaded. I must have broke something to cause a conflict with 'MainCtrl'. it's driving me nuts ! – bob.mazzo Dec 13 '14 at 00:23
  • controller as vm is John Papa style syntax, I believe. it's on the PluralSight course. – bob.mazzo Dec 13 '14 at 00:24
  • 1
    @bob Yeah i know.. that was just in the examples not really for real life usage..IMHO imagine the case (which is most often) you have nested controller what would you name them? vm1 vm2? Also it will be so unreadable and i believe his example were more on attaching controller instance to scope (before the introduction of controllerAs). However my point was different in the comment above.. :) – PSL Dec 13 '14 at 00:35
  • @PSL, point duly noted. thank you. I'm here to learn and appreciate all advice. – bob.mazzo Dec 15 '14 at 16:38

2 Answers2

1
  1. Have a look at other posts (AngularJS error: 'argument 'FirstCtrl' is not a function, got undefined')
  2. Check whether you defined ng-app properly
  3. Check whether you have listed the JS files properly in the index
  4. Try to rewrite your controllers to the more conventional way (see egghead.io tutorials)
Community
  • 1
  • 1
AMG
  • 704
  • 1
  • 8
  • 20
  • 1
    guys, turned out I was loading a bad factory in my index.html. Once I commented it out, my page loaded fine. Please note the "gadgetDataModel" factory which gets injected in my original post. – bob.mazzo Dec 15 '14 at 20:45
0

Maybe you have two files .js with same module name. Eg.:

file1.js:

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

file2.js:

var appControllers = angular.module('appControllers', []);
wibeasley
  • 3,613
  • 1
  • 26
  • 47
bart
  • 1
  • 1