0

I have an AngularJS project which has two views; /settings and /. The app.js file looks like;

.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {

  $routeProvider

  .when('/', {
      templateUrl: './views/bill.html',
      controller: 'BillCtrl'
  })

  .when('/settings', {
    templateUrl: './views/settings.html',
    controller: 'SettingsCtrl'
  })

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

  $locationProvider.html5Mode(true);

}]);

Where all the routes are defined.

Then I have app/views/bill.html & app/views/settings.html.

Now, grunt serve works perfectly where I can go to any view using ngHref. The problem is when I do grunt build and have nginx pointed to the build directory (the path is /kds), I see a GET http://localhost/views/settings.html 404 (Not Found)

The path should be relative, and hence, it should be a GET http://localhost/kds/views/settings.html but that's not the case. What's going on here?

This looks more like a bad server configuration than anything else. Or is the build messing things up for me?

The server directive is;

location /kds { alias /Users/asheshambasta/code/kds/dist/; index index.html index.htm; }

EDIT (full app.js)

'use strict';

angular.module('kdsApp', [
  'ngCookies',
  'ngResource',
  'ngSanitize',
  'ngRoute',
  'apiService',
  'Lib',
  'ngTouch',
  'ipCookie'
  ])

.run(['$location', 'ipCookie', 'APICfg', function($location, ipCookie, APICfg) {
    var login = ipCookie('lgInf');
    if (!login || !login.usr || !login.pass || !login.srv) {
        $location.path('/settings');
    } else {
        APICfg.setSrv(login.srv);
        APICfg.setCId(login.cId);
    }
}])

.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {

  $routeProvider

  .when('/', {
      templateUrl: '/views/bill.html',
      controller: 'BillCtrl'
  })

  .when('/settings', {
    templateUrl: '/views/settings.html',
    controller: 'SettingsCtrl'
  })

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

  $locationProvider.html5Mode(true);

}]);

All the files needed by the application:

  <!-- build:js({.tmp,app}) scripts/scripts.js -->
  <script src="scripts/app.js"></script>
  <script src="scripts/apiservice.js"></script>
  <script src="scripts/lib.js"></script>
  <script src="scripts/class/bill.js"></script>
  <script src="scripts/class/item.js"></script>
  <script src="scripts/class/course.js"></script>
  <script src="scripts/controllers/main.js"></script>
  <script src="scripts/controllers/bill.js"></script>
  <script src="scripts/controllers/settings.js"></script>
  <!-- endbuild -->
Ashesh
  • 2,978
  • 4
  • 27
  • 47

2 Answers2

0

You are placing the website under a subfolder of you host.

Example:

http://localhost/kds

So when you make ng-route work with html5 it will understand that you need to move to '/' because there is no '/kds' defined.

1 trick that you can do is use <base href="/kds">

put this in your <head>

<html>
<head>
    <base href="/kds">
</head>
<body>
    ...
</body>

This will make all your routes or templatesUrls be prefixed with this base.

1st4ck
  • 1,267
  • 11
  • 11
  • I'm afraid that doesn't work for me. Now it begins to look for everything in the root `/` path and the application fails. I also to a `$location.path('/settings')` in my `app.run` if the username/pass is not found, but that isn't the problem. – Ashesh Jun 02 '14 at 16:12
  • I am a litle confused about how you have your source files. My sugestion is for when you have all your source in a subpath of you host inviroment. Example all in the path /kds. – 1st4ck Jun 02 '14 at 16:15
  • Please add the full path of all files required by the aplication. Ex: app.js is on http://localhost/app.js, settings.html is on http://localhost/views/settings.html and so on. i think your problem is about that configuration. – 1st4ck Jun 02 '14 at 16:19
  • I've added all the files I include in index.html – Ashesh Jun 02 '14 at 16:21
  • Your problem is not with the javascript files. it is because of the path angular needs to calculate. when you tell templateUrl: '/views/bill.html' you are telling angular to find the view in `localhost/views/bill.html` open chrome debug tools and check the nagivation tab and see what the link angular is trying to find. them try remove the '/' from templateUrl. – 1st4ck Jun 02 '14 at 16:28
  • I'm afraid removing the `/` from `templateUrl` doesn't work for me either. The link the app is trying to find is not relative, it tries to find `/views` in the root of the server and not relative to where the app is running. – Ashesh Jun 02 '14 at 17:01
0

What I needed in the end was setting up the base href dynamically. Also, the base href has a few gotchas: the relative path should have trailing and leading \; and using javascript you can set it as:

  <script>
    document.write("<base href='" + document.location.pathname + "' />");
  </script>
Ashesh
  • 2,978
  • 4
  • 27
  • 47