AngularJS , Node.js, ExpressJS application integration issue AngularJS , Node.js, ExpressJS application integration issue express express

AngularJS , Node.js, ExpressJS application integration issue


If you're using AngularJS to implement a single-page experience then you should serve the same front-end code every time, and then have AngularJS take over processing the URLs and displaying the content.

Remember that you are managing two routing systems. One for the front-end and one for the backend. Express routes map to your data, usually returned in JSON format. (You can also render html directly, see Option #1.) Angular routes map to your templates and controllers.

Option #1:

Set static folder to serve front-end code (HTML/CSS/JS/AngularJS).

app.use(express.static(__dirname + '/public'));

Look at these for sample code:

Directory Structure:

public/  index.html  js/    angular.js  css/  partials/     partial1.html     partial2.htmlapp/node_modules/routes/web-server.js

Option #2:

Serve the front-end code and backend code on separate servers.

This doesn't mean you have to have two machines.

Here is a workable set up on your local machine with Apache:

Directory Structure:

public/  index.html  js/    angular.js  css/  partials/     partial1.html     partial2.htmlnode/  app/  node_modules/  routes/  web-server.js

Set up hosts file

    127.0.0.1       domain.dev

Set up http://domain.dev/ to point to public/

<VirtualHost *:80>  DocumentRoot "/path/to/public"  ServerName domain.dev  ServerAlias www.domain.dev</VirtualHost>

Set up http://api.domain.dev/ to point to the running node web-server

<VirtualHost *:80>  ServerName api.domain.dev  ProxyPreserveHost on  ProxyPass / http://localhost:3000/</VirtualHost>

(Adapted from: http://www.chrisshiplet.com/2013/how-to-use-node-js-with-apache-on-port-80/)

Start (or restart) Apache and run your node server:

node web-server.js

Angular Routes:

 angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives',    'myApp.controllers'])   .config(['$routeProvider', function($routeProvider) {     $routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl1'});     $routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});     $routeProvider.otherwise({redirectTo: '/view1'}); }]);

index.html:

   <!DOCTYPE html>    <html>     <head><title>Angular/Node exmaple</title></head>     <body>       <div id="main" ng-view></div>     </body>   </html>

Express Routes:

app.get('/', photos.index);app.get('/photos', photos.findAll);

Access these routes in an Angular controller via $http or $resource service:

$http.get('http://api.domain.dev/photos').success(successCallback);

Additional Resources:


I had an existing angular project with a file structure like this (roughly):

/  app/    img/    scripts/    styles/    templates/    index.html  test/

I just created a new express app, and copied the contents of my app directory over to the /public directory in express, after removing all the existing content from /public

Then in the app.js file in express I did the following changes to the default config:

var express = require('express');var routes = require('./routes');// ** required my route modulevar menu = require('./routes/menu'); var http = require('http');var path = require('path');var app = express();// all environmentsapp.set('port', process.env.PORT || 3000);app.set('views', path.join(__dirname, 'views'));app.set('view engine', 'jade');app.use(express.favicon());app.use(express.logger('dev'));app.use(express.json());app.use(express.urlencoded());app.use(express.methodOverride());// ** I moved this above the app.router line below, so that static routes take precedenceapp.use(express.static(path.join(__dirname, 'public'))); app.use(app.router);// development onlyif ('development' == app.get('env')) {  app.use(express.errorHandler());}// ** removed the default index route// app.get('/', routes.index); // ** defined my routeapp.get('/api/menu', menu.list); http.createServer(app).listen(app.get('port'), function(){  console.log('Express server listening on port ' + app.get('port'));});

Then obviously wrote my route file in express and changed the URL in the angular service to use the new api.

Also there was more work involved deciding where to put the specs and also merging the bower and node dependancies etc but that is probably too specific to my situation to include with this answer but happy to share if anyone might find it useful.