Search code examples
angularjsangularjs-routing

AngularJS crashes when I define a route with two parameters in it


As per the title, as soon as I add the route:

    .when('/cluster/:clusterName/node/:nodeId', {
      templateUrl: 'partials/node/view.html',
      controller: nodeViewController
    })

and try to access it, the browser tab crashes with this in the JavaScript console:

RangeError: Maximum call stack size exceeded
    at nodeLinkFn (http://127.0.0.1:8080/libs/angular/angular.js:6695:34)
    at compositeLinkFn (http://127.0.0.1:8080/libs/angular/angular.js:6086:13)
    at compositeLinkFn (http://127.0.0.1:8080/libs/angular/angular.js:6089:13)
    at compositeLinkFn (http://127.0.0.1:8080/libs/angular/angular.js:6089:13)
    at compositeLinkFn (http://127.0.0.1:8080/libs/angular/angular.js:6089:13)
    at publicLinkFn (http://127.0.0.1:8080/libs/angular/angular.js:5982:30)
    at link (http://127.0.0.1:8080/libs/angular-route/angular-route.js:919:7)
    at nodeLinkFn (http://127.0.0.1:8080/libs/angular/angular.js:6692:13)
    at compositeLinkFn (http://127.0.0.1:8080/libs/angular/angular.js:6086:13)
    at publicLinkFn (http://127.0.0.1:8080/libs/angular/angular.js:5982:30) <div class="col-lg-12 ng-scope" ng-view=""> 

I don't understand why this happens and don't really know to debug it further as I am new to AngularJS. Here is my full app.js:

'use strict';

angular.module('dopeFrontend', ['ngRoute', 'ngResource'])
    .run(function($http, $rootScope, $location) {
      //$http.defaults.headers.post['X-CSRFToken'] = $('input[name=_csrf_token]').val();
      $rootScope.location = $location;
    })
    .config(['$routeProvider', '$locationProvider',
      function($routeProvider, $locationProvider) {
        $routeProvider
            .when('/', {
              templateUrl: 'partials/core/clusters.html',
              controller: indexController
            })
            .when('/login', {
              templateUrl: 'partials/auth/login.html',
              controller: loginController
            })
            .when('/create', {
              templateUrl: 'partials/core/create_cluster.html',
              controller: clusterCreateController
            })
            .when('/connect', {
              controller: clusterConnectController
            })
            .when('/cluster/:clusterName', {
              templateUrl: 'partials/cluster/overview.html',
              controller: clusterOverviewController
            })
            .when('/cluster/:clusterName/nodes', {
              templateUrl: 'partials/node/nodes.html',
              controller: nodesViewController
            })
            .when('/cluster/:clusterName/node/add', {
              templateUrl: 'partials/node/add.html',
              controller: nodeAddController
            })
            .when('/cluster/:clusterName/node/:nodeId', {
              templateUrl: 'partials/node/view.html',
              controller: nodeViewController
            })
            .otherwise({
              redirectTo: '/'
            });
        $locationProvider.html5Mode(true).hashPrefix('!');
      }]);

I am using AngularJS 1.2.22, Google Chrome 36.0.1985.125 and the AngularJS app is served through a local Nginx server. Here's the relevant config:

root   /Users/alex/dev/dope/dope/static;
index index.html;

location / {
    expires -1;
    add_header Pragma "no-cache";
    add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
    try_files $uri $uri/ /index.html =404;
}

How can I fix this or debug it further?


Solution

  • I've just found that the <base> tag is required for relative urls in HTML5 mode.

    It is mentioned in this documentation $location guide:

    Relative links

    Be sure to check all relative links, images, scripts etc. You must either specify the url base in the head of your main html file (<base href="/my-base">) or you must use absolute urls (starting with /) everywhere because relative urls will be resolved to absolute urls using the initial absolute url of the document, which is often different from the root of the application.

    Running Angular apps with the History API enabled from document root is strongly encouraged as it takes care of all relative link issues.