3
votes

I have a situation where the Angular $routeProvider appears to not fire controller actions on route changes.

The routes are super simple urls:

window.app = angular.module('app', ['ngRoute', 'app.filters', 'app.services', 'app.directives', 'app.controllers'])
    .config([
        '$routeProvider', function($routeProvider) {
            console.log("app.js config launched");

            $routeProvider
                .when('/nav', {
                    templateUrl: 'temp/test.html',
                    controller: 'navController'
                    // controller: function($scope) { alert('scope called.') }                    
                })
                .when('/home', {
                    controller: 'homeController',
                    template: ' '
                });

            $routeProvider.otherwise({ redirectTo: '/home' });
        }
    ]);

The controller is just an log out to verify access:

app.controller('navController', [
    "$scope", "cellService",
    function ($scope, cellService) {
        console.log("**** navController fired");
    }
]);

The initialization code fires so the routing is initialized. When I hit:

http://localhost:4333/app/#/nav

and the url changes I can see that the test.html template is accessed by the browser, but the controller never fires.

This seems to indicate the route is getting activated by the URL change, but for some reason the controller is not firing. I've tried using a function instead of a controller name, but that too never gets fired. I've also verified that the controller is valid by attaching ng-controller="navController" to an element and that fires the controller just fine.

This is a page that originally didn't have routing associated as it was basically single self-contained page that didn't need navigation. I added the route code after the fact. I added an ng-view (there wasn't one before) after which at least the template started loading - without ng-view nothing happens.

Stumped and not sure what else to look at. Help.

2
So when you go to /nav, you see the html but not the controller? Any chance you're getting an ordering issue? Can you try and put a break point in the creation of the controller is happening too late? - Shawn Wildermuth
No actually what was happening is that the HTML would load in the browser (devtools view) but the controller would not fire. THe html also didn't render. Figured it out - see my answer below. - Rick Strahl

2 Answers

2
votes

It turns out the problem really was operator error on my part, but I think it's a scenario that can cause issues so I'll use this as the answer.

The issue that caused this problem were two-fold:

  • The HTML template HTML page (via templateUrl) had an invalid URL so the page never loaded and the controller wasn't fired because of that.

  • When switching to a template I used an empty template (" ") but had also removed the ng-View directive. The ng-View directive MUST BE present even when using an empty template. Without it the controller doesn't fire.

In both cases it didn't work and I mistakenly assumed that the controller was not getting fired which was confusing because it did fire if I explicitly hooked it up with ng-controller.

Yup plain operator error, but the latter is vitally important - without ng-View the controller doesn't fire.

2
votes

What happens if you define the function externally and reference that? So instead of

.when('/nav', {
                templateUrl: 'temp/test.html',
                controller: 'navController'
                       })

It would be

.when('/nav', {
                templateUrl: 'temp/test.html',
                controller: navController
                              })

and elsewhere

 function navController($scope, cellService){
    console.log("**** navController fired");
 }
 navController.$inject = ['$scope', 'cellService'];