AngularJS – The controller with the name is not registered

When working with AngularJS, it’s possible that simply renaming some files can result in experiencing yet another of its famously frustrating errors. In this case, a ctrlreg error similar to this can result:

angular.js:14700 Error: [$controller:ctrlreg] The controller with the name '' is not registered.

 

Controllers Before Apps

Currently I’m working on an AngularJS 1.6 app using Typescript in Visual Studio. Needing to do some long overdue refactoring I’ve been going around the code modifying type names and namespaces to their final forms. I’ve also needed to rename files to match, which typically start with the name of the class or code unit. Unfortunately changing the names of some of the modules and controllers resulted in a frustrating situation that took some thought to figure out!

My problem was with two files, one of which defined the angular app and the other defined a controller for use through angular routing (shortened for illustration purposes):

// study-analytics-app.ts
angular
    .module('studyAnalyticsApp', [])
    .config(['$routeProvider',
        '$locationProvider',
        ($routeProvider: ng.route.IRouteProvider, $locationProvider: ng.ILocationProvider) => {
        $routeProvider
            .when('/studyanalytics', {
                templateUrl: '/StudyAnalytics/Home',
                controller: 'homeController as homeController'
            })
    }])
    .controller('homeController', StudyAnalytics.HomeController)
// home-controller.ts
module StudyAnalytics {
    export class HomeController {
    }
}

As we’re in ASP.NET MVC land, minification and bundling is taken care of with BundleConfig.cs:

return new Bundle("~/bundles/studyanalytics")
   .IncludeDirectory("~/scripts/studyanalytics", "*.js", true);

In this state the application worked, and refactoring the code resulted with the following code snippets:

// data-analytics-app.ts
angular
    .module('dataAnalyticsApp', [])
    .config(['$routeProvider',
        '$locationProvider',
        ($routeProvider: ng.route.IRouteProvider, $locationProvider: ng.ILocationProvider) => {
        $routeProvider
            .when('/studyanalytics', {
                templateUrl: '/DataAnalytics/Home',
                controller: 'homeController as homeController'
            })
    }])
    .controller('homeController', DataAnalytics.HomeController)
// home-controller.ts
module DataAnalytics {
    export class HomeController {
    }
}

It’s a pretty innocuous change, but once I’d made it the app stopped working and resulted in the following Javascript console error:

angular.js:14700 Error: [$controller:ctrlreg] The controller with the name 'homeController' is not registered

Despite everything, my Google-fu did nothing to help. The top search results for this error message are typically due to mishandling of the module definition, I was pretty sure that’s not what I’d done with a simple copy and replace!

After some frustrating time spent going over and over my code looking for Javascript compilation errors, I decided to try renaming the app module file, as that was the only one that had been changed. I set it back to study-analytics-app.ts, recompiled and refreshed the page. And everything worked.

So the moral of this story is, be careful what order you put your Javascript files in! RequireJS could have avoided the problem, and I should look at getting it in our application if possible. Otherwise, just be sure that the app module is loaded after controllers or any other secondary classes and modules.

Leave a Reply

Your email address will not be published. Required fields are marked *