user3078876
user3078876

Reputation: 157

routing and clean path (no hashtag) not working in angularJS

Guys this is driving me crazy, been fighting for hours on this, and couldn't find a solution!

I know that in order to clean the hashtag from the URL path, i need to use the

$locationProvider.html5Mode(true);

But for some reason this is not working well for me, I'm using tomcat 7 btw to run this.

These are my HTML imports, both AngularJS stuff are v1.2.6:

    <script type="text/javascript" src="angular/angular.min.js"></script> 
    <!-- Angular Libraries -->
    <script type="text/javascript" src="angular/angular-route.js"></script>
    <!-- This one handles the alert notifications -->
    <script type="text/javascript" src="angular/angular-flash.min.js"></script>

    <!-- App related libraries -->
    <script type="text/javascript" src="js/services/portfolioServices.js"></script>
    <script type="text/javascript" src="js/controllers/myWorkControllers.js"></script>
    <script type="text/javascript" src="js/controllers/navController.js"></script>
    <script type="text/javascript" src="js/controllers/aboutController.js"></script>
    <script type="text/javascript" src="js/controllers/contactController.js"></script>
    <script type="text/javascript" src="js/directives/portfolioDirectives.js"></script>

Then this is my Service javascript with the config

portfolioApp = angular.module('portfolioApp', ['ngRoute']);

portfolioApp.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
    $routeProvider
        .when('/mywork', {
            templateUrl: 'partials/mywork.htm',
            controller: 'myWorkController'
        })
        .when('/about', {
            templateUrl: 'partials/about.htm',
            controller: 'aboutController'
        })
        .when('/contact', {
            templateUrl: 'partials/contact.htm',
            controller: 'contactController'
        })
        .otherwise({redirectTo: '/mywork'});    
        $locationProvider.html5Mode(true);
}]);

Each of those controllers is only defined, nothing special, the name and the function injecting the $scope. Nothing in them.

Basically, the URL without using the html5Mode is

http://localhost:8080/template/#/

I would like to be:

http://localhost:8080/mywork
http://localhost:8080/about
http://localhost:8080/contact

Now, i could make it work... by accessing to http://localhost:8080/template it gets redirected to those url's above... but when i refresh the page with Ctrl+F5, i get a 404 Not Found from Tomcat! :S how come?? the path shouldn't be solved by angular?

Please what am I doing wrong in here? I'm really getting mad hahah

Btw, just in case you want to know how my project directory is, here's a screeshot of it:

http://puu.sh/5UI0Z.png

This is my current web.xml

<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>Portfolio Application</display-name>

    <!-- Auto scan rest service -->
    <context-param>
        <param-name>resteasy.scan</param-name>
        <param-value>true</param-value>
    </context-param>

    <context-param>
        <param-name>resteasy.servlet.mapping.prefix</param-name>
        <param-value>/rest</param-value>
    </context-param>

    <listener>
        <listener-class>
            org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
    </listener>


    <servlet>
        <servlet-name>resteasy-servlet</servlet-name>
        <servlet-class>
            org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>resteasy-servlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

</web-app>

Thanks in advance.

Upvotes: 2

Views: 3416

Answers (3)

user2297584
user2297584

Reputation: 1

I resolve this issue by adding a in web.xml

When you refresh the target page manually, will redirect the 404page to your main page. And then angular router will take in effect to route this to target page.

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691715

When you hit F5, you're not using an angular directive or anything angular-related. You simply tell the browser to send a new request to the URL that is currently in the address bar, and to refresh the page with what comes back from the server. So if the current location is http://localhost:8080/mywork, a request will be sent to http://localhost:8080/mywork, and if the server doesn't have anything configured to handle this URL, you'll get a 404.

Now, if you configure the server to return the main angular HTML page when the URL /mywork is hit, then the browser will display this HTML page and execute the JavaScript it contains. The angular router will detect that the location is /mywork, and it will thus load the partial and the controller associated with this location, and display the appropriate template.

The old, hashbang-based routing doesn't need any configuration of the backend because the URL is always the same. Only the part after the hashbang (unknown by the server), changes.

Upvotes: 1

plalx
plalx

Reputation: 43718

I haven't tried myself yet, but from what I know, you have to make sure that your server simply returns your initial HTML page for these non-existing URLs. Then when the page will reload, an onload event will be fired and you can access the last state via history.state. I guess angular will just restore the state automatically so you shouldn't have to worry about this.

Upvotes: 0

Related Questions