4
votes

I know there are answers to this question, but they're not fully working for me. I'm using Angular 1.4 and Express 4. Express is handling API calls and Angular is supposed to be handling all HTML.

My express app.js:

var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

require('./routes/api')(app);

var app = express();

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());

app.use(express.static(path.join(__dirname, '../client')));
// This covers serving up the index page
app.use(express.static(path.join(__dirname, '../client/.tmp')));
app.use(express.static(path.join(__dirname, '../client/app')));

app.all('*', function(req, res) { 
  res.redirect('/index.html'); 
});

module.exports = app;

Here is angular app.js

angular
  .module('punyioApp', [
    'ngAnimate',
    'ngAria',
    'ngCookies',
    'ngMessages',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch'
  ])
  .config(function ($routeProvider, $locationProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl',
        controllerAs: 'main'
      })
      .when('/howitworks', {
        templateUrl: 'views/howitworks.html',
        controller: 'HowItWorksCtrl',
        controllerAs: 'howitworks'
      })
      .otherwise({
        redirectTo: '/'
      });

      $locationProvider.html5Mode(true);
  });

Now, if I go to http://localhost:3000/, I get the main Angular view, as expected. The problem is when I go to http://localhost:3000/howitworks, which redirects me to http://localhost:3000/index.html and does not show the 'howitworks' view. How do I fix the express router so that I can go to http://localhost:3000/howitworks ?

3
Why are you using app.all(*... and not simply app.get('/', ....? Thanks. - R.A. Lucas
My client is a separate project, essentially. The express app doesn't have a 'howitworks' endpoint. My Angular code understands it, though. I'm looking for how to send the unknown URL to Angular. - Nik
And if I can redirect to index.html, it seems like I should be able to send this to Angular somehow that works for Angular. - Nik

3 Answers

14
votes

Your code is simply redirecting every request to index.html, which isn't what you want. You do need that file, but since Angular handles the routing, you only want Express to send the file, no questions asked.

Basically, you shouldn't be using redirect, but sendFile:

app.get('/*', function(req, res) { 
  res.sendFile(__dirname + '/index.html')
});

Also, as someone pointed out in the comments, you should use get and not all.

0
votes

If you are using angularjs ui-router ,there is no need to use express,you can use node-static or just nginx ,and use grunt or gulp connect plugin to dubug,I think it's better this way.

0
votes

In case of jade you can use:

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