1

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!

jeh
  • 2,373
  • 4
  • 23
  • 38
  • Need more code. That is a factory service, but I don't see where/how it is used. I don't see your angular routes. Also, I don't see a route for `/offers/:offerId` in express here. – TheSharpieOne Jan 30 '14 at 14:06
  • app.get('/offers', offers.all); will handle /offers/:offerId :offerId is only added if it is a param. Will add some more code. – jeh Jan 30 '14 at 14:13
  • Can you check this url http://stackoverflow.com/questions/15206610/how-to-have-express-routing-work-with-angular-routing-with-html5-style-urls – JQuery Guru Jan 30 '14 at 14:14
  • check this too: http://stackoverflow.com/questions/21067717/angularjs-and-express-routing-issue/21067807#21067807 – Ilan Frumer Jan 30 '14 at 15:28

1 Answers1

2

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.

Community
  • 1
  • 1
TheSharpieOne
  • 25,646
  • 9
  • 66
  • 78
  • This is what I originally thought was happening. What is actually happening is when I include app.get('/*', function(req, res) { res.render('index'); }); it doesn't bring back the offers but when I comment it out it does. So this is matching /offers and rendering the index even though it is after app.use(app.router) – jeh Jan 30 '14 at 15:02
  • Does `app.get('/*', function(req, res) { res.render('index'); });` appear before or after `app.get('/offers', offers.all);` ? You need to post the whole thing, or at least larger section. Order matters. – TheSharpieOne Jan 30 '14 at 15:05
  • added more code above...app.router appears above the app.get('/*') but this is definitely called and renders the index page when angular requests /offers/ – jeh Jan 30 '14 at 15:12
  • Your edit is correct, I thought app.router told express to look at routes.js. Thanks for the help. – jeh Jan 31 '14 at 01:25