1

Using ui-router with AngularJS application, It don't render the views correctly.

That's the app.js file implementation:

'use strict';

angular.module('myApp', [
   'ngCookies',
   'ui.router'
]);

angular.module('myApp').config(['$stateProvider', '$urlRouterProvider', '$locationProvider', '$httpProvider',
function($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider){

    // Login Route
    $stateProvider.state('login', {
        url: '/login',
        templateUrl: '/app/views/login.html',
        controller: 'loginController'
    });

    $stateProvider.state('home', {
        url: '/home',
        templateUrl: '/app/views/home.html'
    });

    $urlRouterProvider.otherwise('/home');

    $locationProvider.html5Mode(true);
}]);

And that's the index.html:

<!DOCTYPE html>
<html class="no-js" lang="en" data-ng-app="myApp">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" href="./vendor/bootswatch/bootstrap.css" media="screen">
    <link rel="stylesheet" href="./vendor/bootswatch/bootswatch.min.css">
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css">
    <link rel="stylesheet" href="./css/style.css">

    <script src="./bower_components/angular/angular.min.js"></script>
    <script src="./bower_components/angular-route/angular-route.min.js"></script>
    <script src="./bower_components/angular-cookies/angular-cookies.min.js"></script>
    <script src="./bower_components/angular-ui-router/release/angular-ui-router.min.js"></script>
    <script src="./app/app.js"></script>
    <script src="./app/modules/login/module.js"></script>
    <script src="./app/modules/home/module.js"></script>
</head>

<body data-ng-cloak>

    <div class="container" data-ui-view></div>

    <script src="./vendor/jquery/jquery-1.10.2.min.js"></script>
    <script src="./vendor/bootstrap/js/bootstrap.min.js"></script>
    <script src="./vendor/bootswatch/bootswatch.js"></script>
</body>
</html>

The problem is that when starting the app and passing to the browser this url (localhost:8000/login) or (localhost:8000/home), It responds with (Not Found)

The cause of this problem is that the URL don't contain the '#'. Example:

[localhost:8000/#/home] --> works well

[localhost:8000/home] --> don't work at all and shows "Not Found"

Kareem Elshahawy
  • 1,421
  • 1
  • 12
  • 28
  • have you set up any mod-rewrite on server? – charlietfl Jul 05 '14 at 21:52
  • I'm using http-server from npm, just for testing. Is that may cause a problem? – Kareem Elshahawy Jul 05 '14 at 22:14
  • unless you set up a mod rewrite to account for virtual directory..yes – charlietfl Jul 05 '14 at 22:16
  • I tracked the problem and I found that if the '#' is found in the URL, it works fine, otherwise it don't work and redirect to "Not Found" page. Any suggestions? – Kareem Elshahawy Jul 06 '14 at 22:58
  • 1
    that's the whole basis of angular routing ...it is based on the hash. Server doesn't see that as different directory...think links in pages with hash. When you remove hash you need to rewrite url's on server to point at your app entry point. I don't do much in node but the instructions are not hard to find – charlietfl Jul 06 '14 at 23:01
  • if you comment out `html5Mode(true)` will see everything has a hash and works fine – charlietfl Jul 06 '14 at 23:03

1 Answers1

1

The problem is with your .html5Mode(true). You need to update your .htaccess. It all depends on your application, but here is an example of what you can do. This has worked for many Apache users, so hopefully, it will work for you as well.

You also need to take care of the the known <base href> bug found here

<VirtualHost *:80>
    ServerName my-app

    DocumentRoot /path/to/app

    <Directory /path/to/app>
        RewriteEngine on

        # Don't rewrite files or directories
        RewriteCond %{REQUEST_FILENAME} -f [OR]
        RewriteCond %{REQUEST_FILENAME} -d
        RewriteRule ^ - [L]

        # Rewrite everything else to index.html to allow html5 state links
        RewriteRule ^ index.html [L]
    </Directory>
</VirtualHost>

Source: This post.

Community
  • 1
  • 1
Kousha
  • 32,871
  • 51
  • 172
  • 296