How to use AngularJS routes with Express (Node.js) when requesting a new page?

I am using Express, which loads AngularJS from a static directory. I usually ask for http://localhost/ , in which Express serves me index.html and all the correct Angular files, etc. In my Angular app, I have these route settings that replace the contents in ng-view :

 $routeProvider.when('/', { templateUrl: '/partials/main.html', controller: MainCtrl, }); $routeProvider.when('/project/:projectId', { templateUrl: '/partials/project.html', controller: ProjectCtrl, }); $locationProvider.html5Mode(true); 

On my main page, I have a link to <a href="/project/{{project.id}}"> , which will successfully download the template and redirect me to http://localhost/project/3 or any other identifier, which I indicated. The problem is that when I try to direct my browser to http://localhost/project/3 or refresh the page, the request is sent to the Express / Node server, which returns Cannot GET /project/3 .

How do I set up Express routes for this? I assume this will require the use of $location in Angular (although I would prefer to avoid the ugly searches and # hashes that they use), but I don't know how to start setting up Express routes to handle this.

Thank.

+46
angularjs express
Nov 04 '12 at 19:52
source share
3 answers

I would create a catch-all handler that runs after your regular routes that send the necessary data.

 app = express(); // your normal configuration like `app.use(express.bodyParser());` here // ... app.use(app.router); app.use(function(req, res) { // Use res.sendfile, as it streams instead of reading the file into memory. res.sendfile(__dirname + '/public/index.html'); }); 

app.router is middleware that runs all your express routes (e.g. app.get and app.post ); usually Express automatically puts this at the end of the middleware chain, but you can also add it to the chain explicitly, as we did here.

Then, if the URL is not processed by app.router , the latest middleware will send the Angular HTML view down to the client. This will happen for any URL that is not handled by other middleware, so your Angular application will have to handle the wrong routes correctly.

+39
Nov 05 '12 at 7:35
source share

with expression 4, you probably want to catch all requests and redirect to the angularjs index.html page. app.use(app.router); no longer exists and res.sendfile deprecated, use res.sendfile with uppercase F.

 app.post('/projects/', projectController.createProject); app.get('/projects/:id', projectController.getProject); app.get('*', function (req, res) { res.sendFile('/public/index.html'); }); 

put all API routes in front of the route for each path app.get('*', function (req, res){...} )

+61
Dec 14 '14 at 10:11
source share

I think I should clarify that I am not interested in using the template engine, but Angular pull out all the partial HTML parts on it, Node works completely like a static server here (but it will not be for the JSON API. Brian Ford shows how to do this using Jade here: http://briantford.com/blog/angular-express.html

My application is a one-page application, so I created an Express route for every possible URL pattern, and each of them does the same.

 fs.readFile(__dirname + '/public/index.html', 'utf8', function(err, content) { res.send(content); }); 

I assumed that I would have to pass some query variables to Angular, but it seems that Angular does this automatically.

+3
Nov 05
source share



All Articles