3

I have a web app that doesn't seem to work at all if I try to use ngRoute approach to changing primary page view. The routing config looks like:

var app;
app = angular.module('genehaxx', ['ngGrid','ngRoute', 'ngSanitize', 'ui.bootstrap','genehaxx.filters', 'genehaxx.services'])
.config(function($routeProvider){
        //route setup
  $routeProvider
    .when('/workflows', {
        templateURL: '/partials/workspace_view.html',
        controller: 'MainController'
    })

    .when('/jobs', {
        templateURL: '/partials/submissions_view.html' ,
        controller: 'MainController'
    })

    .when('/', {
        templateURL: '/partials/analyses_view.html',
        controller: 'MainController'
    })

    .when('/analyses', {
            redirectTo: '/'
        })

    .otherwise({
            redirectTo: '/'
    });

});

function MainController($scope, $modal, $rootScope, User, Data, Workflow, Step){
  //lots of proprietary code here..
}

I have tried it with and without the '/' in front of partials. I have tried it both with its normal web-server reverse proxied under nginx and directly under http-server from its directory. In both cases there is no evidence whatsoever that the partials pages are ever requested from the server. The main view is a bit hairy to post in entirety but the relevant bits look like:

<!doctype html>
<html lang="en" ng-app="genehaxx" >
<head>
  <meta charset="utf-8">
  <title>Welcome to Genengine!</title>
  <link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css" rel="stylesheet" />
  <link rel="stylesheet" href="css/app.css"/>
  <link rel="stylesheet" href="css/ng-grid.css">

  <script src="lib/jquery-2.0.2.js"></script>
  <script src="libs/angular/angular.js"></script>
  <script src="libs/angular-route/angular-route.min.js"></script>
  <script src="libs/angular-sanitize/angular-sanitize.js"></script>
  <script src="lib/transition.js"></script>
  <script src="lib/bootstrap-custom/ui-bootstrap-custom-tpls-0.10.0.js"></script>
  <script src="lib/ng-grid-2.0.7.debug.js"></script>
  <script src="js/app.js"></script>
  <script src="js/filters.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore.js"></script>
  <script src="js/objects.js"></script>
  <script src="js/services2.js"></script>
  <script src="js/dropdownToggle.js"></script>
</head>
<body>
  <div id="main">
    <div ng-view></div>
  </div>
</body>
</html>

I have left off the navbar stuff as it seems irrelevant and I get the same results clicking it or directly entering the url with #whatever. The /libs directories have the latest angular, angular-route, angulare-sanitize from bower.

Small samples I tried plugging in my libraries and partials seem to work which is even more frustrating. I have been stumped on this for days. I hacked around it in production with mess of ng-includes and some "clever" code but I would rather get this working. Anything pop out? When I say it doesn't work, again I mean that I see no evidence that any routing occurred in that these partials are never requested from the server.

  • If you manually go to the url: `http://yourserver.com/partials/workspace_view.html` in your browser, does it correctly load the partial? – GregL May 22 '14 at 23:52
  • can you please add the controller code as it would help see if there are issues there causing the routing not to work – Jared Reeves May 23 '14 at 00:12
  • You are loading MainController twice. Once in and again for each view. Not sure that's a good idea. – aet May 23 '14 at 00:16
  • The controller is a bit complicated and proprietary to the project. But I will add its declaration above. –  May 23 '14 at 00:21
  • I moved the ng-controller line to the navbar div that I didn't list as it is an old school ugly navbar that has a drop down that needs stuff from the $scope. Changing the listing accordingly. –  May 23 '14 at 00:27

3 Answers3

5

You have typos inside of your when calls:

Example:

templateURL: '/partials/workspace_view.html',

should be

templateUrl: '/partials/workspace_view.html',

(notice the difference in caps, templateURL changes to templateUrl)

Nikhil
  • 3,590
  • 2
  • 22
  • 31
Marc Kline
  • 9,399
  • 1
  • 33
  • 36
  • D'oh! It is templateUrl and I had templateURL everywhere. Man do I ever feel dumb. Thanks everyone. That fixed it. –  May 23 '14 at 00:31
  • I found it by copy/pasting your code into a Plunker to make an abstract version of your app which I knew did not have any complications from file or code dependencies. Then I knew there was something off in your demo code itself and just took a closer look. I mention this all just to say that rewriting the relevant bits of your code to isolate the problem can be very helpful :) – Marc Kline May 23 '14 at 00:35
1

Couple things

1 - Stringify MainController

.

$routeProvider
.when('/workflows', {
  templateURL: '/partials/workspace_view.html',
  controller: 'MainController'
})

.when('/jobs', {
  templateURL: '/partials/submissions_view.html' ,
  controller: 'MainController'
})

.when('/', {
  templateURL: '/partials/analyses_view.html',
  controller: 'MainController'
})

.when('/analyses', {
  redirectTo: '/'
})

.otherwise({
  redirectTo: '/'
});

2 - You don't need ng-controller on body. ngRoute will bind the controller to the view for you. However, make sure you have MainController defined in your app, otherwise angular will throw an error at you

bioball
  • 1,339
  • 1
  • 12
  • 23
  • Thanks. Don't know how those got unstrigified. But fixing that makes no difference. Working examples I have played with sometimes have the controller defined in the main view and sometimes not. Doesn't seem to make a difference either way. –  May 22 '14 at 23:53
  • You can also try putting `ng-app` on the `body` tag. I've never seen it defined on `html` before, and that might fix your problem. – bioball May 23 '14 at 00:28
0

I see that @Mark Kline's solution solved your issue, but I would like to make suggestion that might help you in the long run.

You mention in a comment that your controller is complicated, as such I would highly recommend that you break it up into smaller controllers where each is used only to control one of the routes. From experience if you are using routing to develop an application then using one controller is going to get very large quickly, and in the long run be very hard to maintain. I have tried, in previous apps to use a single controller for several different views and it tends to get out of hand rather quickly.

If you are able, I highly suggest that you separate as much functionality as possible to save yourself a lot of future headaches, it is going to make your code easier to read, maintain, and debug.

Jared Reeves
  • 1,390
  • 2
  • 15
  • 29
  • Thanks. It is partially complicated because when I wrote it I didn't know angularjs as well. I also exposed some things at $scope level that made the view run smoother with no complaints that something it was recomputing often was too heavy. There are other ways to factor those that I know now like doing more in Factories and Services than I did before. But frankly I still get spooked by the $scope madness of anguraljs. It is not so easy to know what is and is not visible up the $parent chain, especially across directives. More learning to do I guess. –  May 23 '14 at 03:19
  • Always remember that you only need objects in the scope if they are going to be used in the dom. If an object is not need by the dom then use classic closure to keep the global name space unpolluted. Also, services/factories and directives are your friends and provide proper two binding and code reuse throughout the code. – Jared Reeves May 23 '14 at 03:29