Html5 mode Angularjs Express URL rewrite returns index page for ALL requests

I've been using similar questions to try and find the solution to the problem I'm having. I understand that in order to use html5Mode with angularjs I need to tell the server how to handle a direct visit to a page.

I have the issue where clicking on the link within the app renders the page fine but a direct visit does not display offers.

E.g.

http://localhost:3001/offers/television/

should call in routes.js

app.get('/offers', offers.all); 

and it does when the link

  <a href="offers/television">televisions</a>

is clicked

When I directly visit it however it looks like my angular service is returning the index page as resources...!

//Offers service used for offers REST endpoint
 angular.module('mean.offers').factory("Offers", ['$resource','$routeParams',function($resource,$routeParams) {
   return $resource('/offers/:offerId', 
     {offerId: '@_id'},
       {
         search: {'method': 'GET', params: {}, isArray:true}
       });
     }]);

I've also got base(href="/") in my index.jade head

angular config.js

//Setting up route
window.app.config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.
      when('/offers/:type/',{
        controller: 'OffersController',
        templateUrl: 'views/offers/list.html'
      }).
      when('/', {
        templateUrl: 'views/index2.html'
      }).
      otherwise({
        redirectTo: '/'
      });
    }
 ]);
 //Setting HTML5 Location Mode
 window.app.config(['$locationProvider',
   function($locationProvider) {
     $locationProvider.hashPrefix("!");
     $locationProvider.html5Mode(true)
   }
 ]);

express routes.js

//Offer Routes
var offers = require('../app/controllers/offers');
app.get('/offers', offers.all); 
app.get('/offers/:offerId', offers.show);

//Home route
var index = require('../app/controllers/index');
app.get('/', index.render);

express.js

    app.configure(function() {
    // app.use('/', express.static(__dirname + '/'));

    //cookieParser should be above session
    app.use(express.cookieParser());

    //bodyParser should be above methodOverride
    app.use(express.bodyParser());
    app.use(express.methodOverride());


    //routes should be at the last
    app.use(app.router);

    app.get('/*', function(req, res) {
            res.render('index');
    });
 ...

Why is it not returning offers even though it should hit the /offers route in express routes.js? Or am I doing something odd?

Thanks!

Answers


As you mentioned in the comments of the question, "app.get('/offers', offers.all); will handle /offers/:offerId". This means that going directly to http://localhost:3001/offers/television/ will be handled by your offers.all function (not shown in post), not the '/*' handler that returns the index.

To fix this you have options.

  1. Check the route to see if it is an AJAX request or not. If it is, return your data, if it is not, return the index.
  2. Put your API behind a path (like /api) then all of your API requests will go to /api/offers/:offId to get data. This frees up /offers/:offerId to be handled by '/*', returning the index

Edit: I see the confusion, app.router (Node.js / Express.js - How does app.router work?). In a nutshell, app.use(app.router); tells express which order to run the routes as a whole. The order you provide the routes in matter after that point. From your code (again, not showing all of it) you only really define 1 route, app.get('/*', function(req, res) { res.render('index'); });. You have the separate route files, but no where in what you have posted do you includes those scripts. They are not automatically included by default.


Need Your Help

Why java classes do not inherit annotations from implemented interfaces?

java inheritance interface annotations guice

I've been using Guice's AOP to intercept some method calls. My class implements an interface and I would like to annotate the interface methods so Guice could select the right methods. Even if the

callback after remove() to avoid effects take place at the same time

jquery callback

How Can I string these two statements together so the fadeIn of the loader does not happen when the items are faded out.