In the Start an Angular project with Yeoman (Ubuntu 13.4) article (please read this one first or you may have problem following this article), I explained how to start an angular project with Yeoman as well as using Grunt to manage the work flow of your application. However you may wonder when making http requests to the server (back-end), where is that server and how it should be configured. I’ll cover all of that in this article. 

You can use anything for your back-end code. NodeJS with express, Zend Framework, Rails or anything else you prefer. The concept is the same. However if you are using Apache as the web server, you will have to add a virtual host for your back-end code. In this article, I’ll use NodeJs with express as the example. 

Luckily there is Yeoman generator for NodeJs with Express. To install it, simply run the following command in your terminal (I usually install generators on the global scope for convenience )

sudo npm install -g generator-node-express

My personal preference is to leave the angular client side code and the service side code in the same repository. However, they do need to be separated because they are two separate applications. I typically have the following folder structure,

YourApp/client #angularJS client side code
YourApp/server #nodeJS with express service side code

To generate the AngularJs client side scaffolding, you’ll need to run yo angular within the client folder. To create the server side code using Yeoman, simply run yo node-express within the server folder.

You’ll be asked a few questions when installing node-express, but because we don’t need any angular stuff nor the SASS parser, I recommend unticking those options when installing. If you had issues installing, please refer to the official documentation on NPM (https://npmjs.org/package/generator-node-express)

Now we need to start the node server. If you don’t want the faff, just go to YourApp/server and type in

node app.js

This will start your http server on localhost:3000. If you wish to automate the workflow (i.e. automatically restart the server when any watched files are modified, use grunt restart instead).

We now got to the point that we have a server and we can open the browser and type in http://127.0.0.1:3000 to see our server side home page. How exciting! However remember our AngularJS app has been setup on port 9000. Making calls from 127.0.0.1:9000 to 127.0.0.1:3000 is going to cause problems because cross domain traffic is blocked by default unless you deliberately allow it.

To solve this problem, we need to setup a proxy. In other words, this means when accessing 127.0.0.1:9000/api, we’ll tell the server go via 127.0.0.1:3000/api instead behind the scene.

This is done by using the grunt-connect-proxy module which has a very good instruction on https://npmjs.org/package/grunt-connect-proxy. Although this is a indeed very good instruction, I do have a few things to point out because I got stuck on this for a few hours due to the lack understanding of grunt.

  • Under the connect:proxies section, the context has a value of ‘cortex’. This  means your 127.0.0.1:9000/cortex route is pointing to 127.0.0.1:3000/cortex not 127.0.0.1:3000. I thought it was going into the top level route but apparently it didn’t.
  • The next thing is it’s really useful to use the –verbose option when running grunt server. i.e. grunt server –verbose. This is going to give you very detailed output when starting the server and on top of that, you’ll also see access logs in the terminal. i.e.
Proxied request: /api/home -> http://localhost:3000/api/home
{
    "host": "127.0.0.1:9000",
    "connection": "keep-alive",
    "content-length": "2",
    "accept": "application/json, text/plain, */*",
    "origin": "http://127.0.0.1:9000",
    "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36",
    "content-type": "application/json;charset=UTF-8",
    "referer": "http://127.0.0.1:9000/",
    "accept-encoding": "gzip,deflate,sdch",
    "accept-language": "en-GB,en-US;q=0.8,en;q=0.6",
    "cookie": "_ga=GA1.4.194784887.1384818518"
}

That’a pretty much it. Grab it and have fun!