3

When I try to bind a controller to a template using the angular-ui-router $stateProvider, I run into the following error:

'ShouldWorkController' is not a function. Got undefined.

However, when I declare the controller inside the template using ng-controller, everything works fine. What could be wrong here?

app.ts

module App {

    var dependencies = [
        MyControllers            
    ]

    function configuration($stateProvider: ng.ui.IStateProvider) {

        $stateProvider
            .state("shouldWork", {
                url: "/shouldWork",
                templateUrl: "app/shouldWork.html"
                controller: "ShouldWorkController" // does not work
           });
    }
}

shouldWorkController.ts

module App.MyControllers {

    interface IShouldWorkViewModel {

    }

    class ShouldWorkController implements IShouldWorkViewModel {}

}

ShouldWork.html

<div ng-controller="ShouldWorkController as viewModel" us-spinner spinner-key="spinner-1">
                 ^ --- this works nicely
tereško
  • 58,060
  • 25
  • 98
  • 150
xvdiff
  • 2,179
  • 2
  • 24
  • 47

2 Answers2

2

That message means, that such controller "ShouldWorkController" is not loaded int he main angular module. Be sure that you do call register at the end:

module App.MyControllers {    
    ...
    class ShouldWorkController implements IShouldWorkViewModel {}    
}

// we have to register this controller into some module (MyControllers)
// which is also referenced in the main app module
angular.module('MyControllers')
    .controller('ShouldWorkController', App.MyControllers.ShouldWorkController ); 
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • I'm using grunt-tsng which automatically registers controllers etc. on build, which also works fine (else the controller declaration inside the template wouldn't work anyway). – xvdiff Jan 04 '15 at 11:08
  • The message is clear - the `angular.module('app', [..])` is not having access to your controller. That's the message. So the registration via your grunt stuff is not working properly. The main module does not have such name registered. Does it help? – Radim Köhler Jan 04 '15 at 11:09
  • I understand what you are saying, it just makes no sense to me as everything that needs to be here is there (and binding the controller using 'ng-controller' works perfectly fine). Excerpt from the generated js code: `(function (App) { function (MyControllers) { var ShouldWorkController = (function ()...` and later `angular.module("App.MyControllers").controller("ShouldWorkController,` – xvdiff Jan 04 '15 at 11:18
  • 1
    The point now is: I really would suspect this: the module app is missing that controllers module. Check twice that you see `angular.module("App", ["App.MyControllers", ...])`. That would be the reason in 95%. The rest 5% is that your controller generated file is not embedded into the page. I am really almost sure about it... – Radim Köhler Jan 04 '15 at 11:23
0

I realise this is old, but I came here via Google with the same issue, not for the firs time. Things to check include:

  1. Export statement for your controller class. From the code you posted I see that you are missing an export statement for your ShouldWorkController class. This may not be the issue in your case, but it is something you should check. I can reproduce this error by removing the export statement from my controller classes.
  2. Check your HTML template exists (if using UI-Router). As described in the UI-Router documentation: "The controller will not be instantiated if template is not defined."
  3. Register your controllers in the same file as the controller. Some tutorials do demonstrate controllers being registered in the module file. While this does work, I personally have found it more error prone than directly registering the controller within the controller file.
  4. Check your typescript references. Make sure that you add typescript references (e.g. ///<reference path="../app/services/shouldWorkService.ts">) to typescript files that contain any types that you reference
  5. Check the name of your controller matches that declared in your $stateProvider configuration.
Blake Mumford
  • 17,201
  • 12
  • 49
  • 67