Using heroku for Sencha Touch demo site

I needed to put a demo Sencha Touch app to showcase some of features of the framework. I wanted to put this somewhere that I could easily put up and take down if required. Currently I have no domain space that was suitable so decided to use Heroku for the job mainly to see what steps were required to get such a thing working with node.js.

The solution was quick and easy to implement.

Firstly I created a node.js script  to do the serving of the page. The script was not all that different from the example in this tutorial, which used the node-static npm

var static = require('node-static'),
  http = require('http'),
  util = require('util');
var webroot = './sencha',
  port = process.env.PORT || 5000;

var file = new(static.Server)(webroot, {
  cache: 600,
  headers: { 'X-Powered-By': 'node-static' }
});
http.createServer(function(req, res) {
  req.addListener('end', function() {
    file.serve(req, res, function(err, result) {
      if (err) {
        console.error('Error serving %s - %s', req.url, err.message);
        if (err.status === 404 || err.status === 500) {
          file.serveFile(util.format('/%d.html', err.status), err.status, {}, req, res);
        } else {
          res.writeHead(err.status, err.headers);
          res.end();
        }
      } else {
        console.log('%s - %s', req.url, res.message);
      }
    });
  });
}).listen(port);
console.log('node-static running at http://localhost:%d', port);

I knew this script was very basic but as I didn’t have much time to do this (literally an evening), and it worked I decided to go with it.

I put all the sencha code into a sub folder called “sencha” and saved the javascript above as server.js. I then tested running it locally by using command “node server.js”. Browsing to http://localhost:5000 brings up ./sencha/index.html, which in turn should load up the sencha app. It seems node-static, like any web server, defaults to index.html in the absence of any specific request.

This all worked fine so to get the app on heroku. I had to add a Procfile and a package.json file. The Procfile just had one line; web: node server.js. The package.json file contained the node-static npm version:

{
  "name": "static",
  "version": "0.0.1",
  "dependencies": {
    "node-static": "0.6.4"
  }
}

You must have the correct version for any npm’s used or heroku will crash when deploying. To make sure you have this, execute the following locally:npm list. This will list all npms saved and their versions.

Once you have everything in place you can deploy to Heroku using their instructions: https://devcenter.heroku.com/articles/nodejs

Advertisements

Next steps on the Node.js/MongoDB adventure (introducing Sencha Touch 2)

My previous post described the long (at times arduous…) journey I took creating my first project with Node.js and MongoDB. The next project is to start building a map application based on the web app I built for artsfest 2011. The new app will do exactly the same and will use the same Sencha Touch framework for the UI, but will be totally different in the background using Node.js and MongoDB to feed the data.
Data

The first job is to work out the data requirements. For now I just need Markers and what I call Pois (Points Of Interest) which can be found at each Marker. In SQL world these would be two tables with the Marker ID as a Foreign Key in the Poi table, using a one to many relationship between Marker and Poi. In MongoDB world this would be two collections – all the examples I’ve seen so far use just one collection. This MongoDB tutorial suggests a starting point, using two collections (postings and users) and showing a reference between the two using the Simple Direct/Manual Linking method. So I think I will be creating two collections in a new database – Marker and Poi, with a Marker id being used as a reference in the Poi table.

To create the database is easy in the Mongo Shell

>use PoiPoi

Next is to create a collection, but rather than type it in I’d like to import from a file. This will enable me to use existing data and play about with the data until I’m happy with what I have.

To import data, first I prepared a json file to import, named “Marker.json”. This json contains the markers for my map. The most important thing here is to remove any whitespace, but configure it so that each new entry (document) starts a new line. Here is an excerpt of the file:

{ "MarkerID": 78, "title": "Birmingham Conservatoire", "long":"-1.905345", "lat": "52.479278", "icon": "artsfest.png", "description": "Home to classical music"}
{ "MarkerID": "37", "title": "Birmingham Museum and Art Gallery","long": "-1.903714","lat": "52.480173","icon": "artsfest.png","description": "The City's Art Gallery - the home of the PRB collection amongst other fine art works."}

from a new terminal window I then entered the following to import the data:

>mongoimport -d PoiPoi -c marker /home/alex/Mongo/Marker.json

To delete data from the collection execute the mongo command remove():

>db.marker.remove()

If you want to completely remove the collection then execute.

>db["marker"].drop()

Creating the Pois was a similar process. I just made sure each item had a “MarkerID” entry. I then imported the poi data using the mongoimport command.

Once I had both a marker and poi collection I could query them. What I wanted to do first is find all Pois with the same markerID, which could be done with the following command:


db.poi.find({"MarkerID":78})

Sencha

The next step is to build a basic sencha script to query the data and return a list of markers, then by clicking on a marker, it gives you a list of pois for that marker.

Back to Express

For this application I wanted to use Sencha and merge it with using Node.js somehow. I quickly realised that Express is the answer to this. Express can be used just to enable routes by using an instance:

var app = require('express').createServer();

app.get('/', function(req, res){
res.send('hello world');
});

app.listen(3000);

But you can also create a template application to work off by executing:


$ npm install -g express
$ express /tmp/foo && cd /tmp/foo

This will populate foo directory with subdirectories and files to get your app started. You can use the app straight away by executing:


$ node app.js


Coding the application

With the data and the application framework set up, I began writing the Sencha part of the app. The github home for the app is at https://github.com/lalexgraham/NodeSenchaMVC/ and has gone through 4 commits (and counting) already. I have found I have had to start off very basic. So a lot of the commits are nothing like the intended finished app, rather just basic apps to find out how to do certain things. In brief, this is what I have done so far

1st commit

For this commit I just wanted to set up the basic architecture of the site and get it reading data from MongoDB. So as usual with a node.js application, app.js at the root folder is the starting point. The Public directory contains the Sencha files, which includes the MVC folders: views, controllers, models, store. Running the app displays a list of the marker titles that are pulled through from MongoDB. I chose a list as this is the easiest way to display data pulled from a proxy but this has to be replaced by a map for the final version.

2nd commit

For the 2nd commit I got rid of the list and replaced it with a map. I then got a marker onto the map through the controllers/Map.js file.

3rd commit

Up until this commit I had been working with Sencha Touch 1.x….and then I noticed that Sencha Touch 2 beta is now avalailable. I thought that because I had only just started the app, I might as well write it using the latest version of Sencha Touch. So this commit was to start using Sencha Touch 2, going back to a basic application, just rendering “Hello World” and calling a view (/public/app/view/Viewport.js) that’s not fully implemented yet. The only part of the application code missing from this commit is the actual Sencha code library. This is basically the whole of the Sencha Touch 2 download put into a folder called Touch. This folder is huge but I haven’t figured out yet the minimum files I need. I have added a .gitignore file in the root of the app to ignore the Touch directory for Git and stop the repos getting bloated. The next job is to get the application back to how commit 2 looked using Sencha Touch 1.x.

4th Commit

Back to basics… Sencha Touch 2 has got me a bit flummoxed. I think I am trying to run before I can walk with using the new framework so this version has gone back to basics so I understand how views and switching between them works. To begin with I just want to show two views using the new MVC architecture that Sencha Touch 2 provides. I read up some more on the api and downloaded this helpful code example, and adapted it so there is just a Viewport which holds a welcome screen and a map,where you can switch between the two using icons on a toolbar. My next post will describe the basics of this application and how I understand it.

5th Commit

I have centred the map, or at least tried to. There appears to be something wrong in how Sencha Touch interprets Google lat lng coords. i wanted to centre the map on Birmingham city centre, but its more like Northampton. I have successfully added a controller which puts a marker on the map in the intended location – New Street station in Birmingham city centre.

6th Commit Mar 11, 2012

This commit plotted markers stored in a MongoDB collection onto the map. There were two events I wanted to ensure had happened before I plotted the markers. Firstly that the map had rendered and secondly that the store of markers had loaded. I struggled with the right method to do this. I didn’t want to do the plotting within the map view itself or the store for the markers as events, as I understand, should be in controllers. I eventually got the Marker controller (app/controller/Marker.js) to listen for both events. A quick explanation is that the refs and control configuration gets a reference to the Map and reacts to the maprender event by calling putmarkers function. Within this function, a ref for the store is obtained by calling Ext.getStore(). I just noticed I got a reference to the store in the init method as well, which I couldn’t use in putMarkers as it was out of scope. The Each reference created in the refs configuration produces a Setter and Getter method automatically, so this.getMap() gets the reference to the map. A callback function waiting for the store to load ensures the markers are then plotted only when the store has finished loading. The controller took a long time to write and I eventually had to post a question to the sencha forums. The response, from the helpful but concise (guess he needs to be) Mitchell Simeons. The getStore() method got me what I needed. I have learnt the following from this commit:

– If something doesn’t work, go back to basics. I created the marker list to do exactly that when the plotting of markers on the map didn’t work. By doing this I noticed I had a typo in the model, so the store was loading but the data model didn’t render correctly.

– The iconCls which puts the icon image onto the toolbar is limited to those listed under @if $include-default-icons in /home/alex/NodeProjects/NodeSenchaMVC/public/touch/resources/themes/stylesheets/sencha-touch/default/widgets/_buttons.scss . So ‘map’ works but not ‘list’.

So now I have the app reading from and plotting markers from MongoDB. The next step is to complete the application as much as I can before adding localStorage. I may use backbone as well for the admin side of adding editing markers.

7th Commit Apr 7, 2012

This commit took a long time to get to as I had to rethink the whole approach in terms of the views to get to the sequence I wanted. This commit achieves the basic requirement of the app and the sequence I wanted – start from a map, click on marker, show events (items) located at that marker and click on an event (item) to view more detail, reading from the two stores of data (markers and Pois). With the tabBar I didn’t want all the views to appear on the tabBar and I couldn’t quite figure out how to setup this drill down of navigation and have relevant back buttons appearing. For example I couldn’t get setActiveItem working to put the relevant view into the viewport. Using nelstrom’s Presidents example, I found ext.navigation.View, which is an excellent way to utilize a drill down navigation as opposed to the tabBar where all the views are on the tabBar, unless you customize it.

So with Ext.navigation.View, I could push the relevant view into this containing view using events in the Main controller. When pushing the view, a back button appears automatically to pop the view off from the Ext.navigation.View. Very neat.

Apart from a few minor tweaks there is one thing I still need to fix and this I think show my limitations in terms of fully understanding the whole Sencha framework and referencing instances of classes:

I couldn’t reference the title attribute in Poi.view.List from the controller Main. I tried to do this in the showList function. So far I have been referencing views in the refs part of the controller config using their xtypes (Stores are easier as they can be referenced using the getStore function)… I couldn’t reference the instance(s) of Poi.view.List in the refs however as from what I understood of the flow, no instances are there to reference when the app is instantiated which is when, presumably, the refs in the controller do their job.
So from the Presidents example, I found how to reference in the control part of the controller by again using the xtype then the event you want to react to. As well as the disclose event (to show the detailCard) I thought I could use the initialize event to alter the title of the list. Looking at the Sencha Docs, I could see that the first argument you can pass in to this event is the instance of the list component. So I use this reference in the showList function. console.log(list) returns something, but still cannot set the Title. …? So there is something I am missing here.

8th/9th Commit May 16th

This is my final commit for this project. I won’t add more waffle to this post but just to clear up my last problem to assign the title to the list view I used:

main.push({
xtype: 'listCard',
title:item.get('title')
});

This set the title when I pushed the listCard onto the ext.navigation.view.

Making a ToDo list with node.js, MongoDB, Mongoose, MongoHQ, and Heroku

This post describes the process of constructing and deploying a simple ToDo list application using the technologies in the title of the post. The app can currently be found at http://evening-beach-6294.herokuapp.com/. The app can add, list and remove ToDos from the application. I used Ubuntu 11.10 o/s to work on this basic project to help me understand these technologies better as I come from a SQL Server /.Net background.

I hope this post will prove useful to anyone else who is new to these technologies as I have tried to describe everything from the ground up so not to confuse someone, if, like me, you are totally new to all this. I’d welcome any feedback about this post as I hope it does help rather than hinder anyone who is interested in the same things. EDIT: The Node.js source code for the app can now be found at https://github.com/lalexgraham/ToDoList.
The reason I used Ubuntu in the end to complete this project was that I found working with Windows very problematic in particular with using Foreman. My post to Sencha forums here explains more.

The starting point for the app was this post, which quickly showed an example of the javascript to work with, especially for the connection up to MongoDB using the native MongoDB driver.

The steps have been broken down into the following:

1. Install git and node.js
2. Install MongoDB
3. Create node.js application
4. Setup MongoHQ
5. Deploy to Heroku


1. Install git and node.js

To get started with node.js on Ubuntu you can write a simple “hello world” script and view it in the browser. To install node.js on Ubuntu you can use git clone command. If you are unfamiliar with git you can google to find out more about it. git clone copies code located at a url to a location on your hard drive. To install git you have to run these commands in a terminal window on Ubuntu:

sudo apt-get update
sudo apt-get install git-core
sudo apt-get install build-essential
sudo apt-get install libssl-dev

If these go ok, then you can install node.js by entering:

git clone git://github.com/joyent/node.git

This installs node.js at your root directory, so you can change directory to it by typing:

cd node

From within the node directory you can configure and install by typing:

./configure
make
sudo make install

That is node.js installed. To test the install enter the following js into a new file on your text editor

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');

Save the file as example.js within the node folder and then from the same terminal window, enter the following code for node.js to execute the code

node example.js

Browse to the address http://127.0.0.1:1337 and you should see the output ‘Hello World’. You should also see the ‘Server running at http://127.0.0.1:1337/’ output in your terminal window.

2. Install MongoDB

With node.js up and running, setting up MongoDB to test with was next. The stucture of the database was fairly simple. I just wanted the database to have one collection with one document; “title”. The “title” would contain each ToDo. Installing MongoDB was tricky and took a few attempts. As always its a case of googling and eventually finding the right way. This post describes the way I installed MongoDB, which took the following steps. Note that there are other ways to install mongoDB. The steps below are the apt-get install, but this post suggests a different install which, I think, is the “binary” install:

2.1 Add 10gen package to source.list
2.2 Update package
2.3 Add GPG Key
2.4 Install mongodb-10gen
2.5 Done

2.1 Add 10gen package to source.list

from the directory labelled “FileSystem” which I take to understand as the root folder, you can navigate to and open etc/apt/sources.list using your text editor. Paste the following into the sources.list file:

deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen

2.2 Update package

Now you have a path to the installation of MongoDB, if you open a new terminal window and type in:

sudo apt-get update

Ubuntu will pick up on the installation and show output in the terminal window as follows (or something similar)

mongodb-10gen – An object/document-oriented database

2.3 Add GPG Key

To install MongoDB, you need to add a key specific to the MongoDB install with the following terminal command

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10

Note you have to use the sudo keyword which basically gives you admin privileges just for that command

2.4 Finally you can install MongoDB with the following command:

sudo apt-get install mongodb-10gen

10gen is the company that produces MongoDB. Its not a version.

2.5. Done. Hopefully(!) There are a few steps here, which unfortunately means things can go wrong.

Now you have MongoDB installed, you can test the installation by going into the mongo console:

Open terminal window, enter “mongo”, MongoDB starts with a message similar to..

MongoDB shell version: 2.0.2
connecting to: test

The main configuration file “mongodb.conf” is located at “/etc/mongodb.conf“ where you can amend the config if required.

When writing this post and checking MongoDB on my machine I got an error when trying to launch the console:

Error: couldn't connect to server 127.0.0.1 shell/ mongo.js:84

The solution was to uninstall and reinstall MongoDB.

To uninstall use the following command:

sudo apt-get autoremove mongodb-10gen

I then followed steps 1 to 5 noted above, omitting step 3, the GPG key. For some reason MongoDB had previoulsy been shutdown incorectly, which had affected its config. Reinstalling did not lose any data it seems.

So once I had mongodb running, I could add my database and collection to test with. This can be done from the console. If you are used to SQL databases then the syntax and conventions are very different so take some getting used to. This page from the MongoDB website lists some of the commands that prove useful when using the console, and this is a good tutorial. One of the main differences from a SQL setup such as SQL Server is the power of the commands, many of which are implicit. For example, to create a database “test” use the command “use test;”. Technically speaking this doesn’t actually create the database. The database is created “lazily” by inserting data . Next create the collection “todo”, which is done by typing in ‘db.createCollection(“todo”)’. Once the collection is created you can add a document to it by entering:


> todo = {title: "do the food shop"}
{ "title" : "do the food shop" }
> db.todo.insert(todo);

Note, unlike SQL there’s no need to setup a schema for the collection declaring the title as a string, etc. You just do an insert of data to set up the collection. To do a select of the collection you enter a find command:


> db.todo.find()
{ "_id" : ObjectId("4efca8c598c3d71c7a30ded6"), "title" : "do the food shop" }
>

So, now I have the collection in a database that I want being returned through MongoDB. The next step is to build the node.js application.

3. Create node.js application

I then read up more on node.js, and found this tutorial, which I followed and added things like routing to the ToDo List app. The tutorial also introduced npm (node package manager).

So I factored in some of the suggestions from this post to my ToDo app and here is a run through of the code and where it all fits.

The entry point for the application is index.js:

var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers");

var handle = {}
handle["/"] = requestHandlers.list;
handle["/list"] = requestHandlers.list;
handle["/add"] = requestHandlers.add;
handle["/remove"] = requestHandlers.remove;

server.start(router.route, handle);				

This script uses several imports, the first one is server.js:

//Load modules  
var http = require('http');  
var url = require('url');

function start(route, handle) {
  function onRequest(request, response) {
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");
    route(handle, pathname, response, request);
  }

  var port = process.env.PORT || 8888;
  http.createServer(onRequest).listen(port);
  console.log("Server has started on port " + port);
}

exports.start = start;

The start function extracts the pathname (i.e. “/list”) and passes this to the route function, before setting up a port to listen on for requests.

router.js:

function route(handle, pathname, response, request) {
  console.log("About to route a request for " + pathname);
  if (typeof handle[pathname] === 'function') {
    handle[pathname](response, request);
  } else {
    console.log("No request handler found for " + pathname);
    response.writeHead(404, {"Content-Type": "text/html"});
    response.write("404 Not found");
    response.end();
  }
}

exports.route = route;

The route function tries to associate an array item from the handle array with the request made. If successful, the relevant function is called from requestHandler.js, (list, add, remove):

//Load modules  
var http = require('http');  
var url = require('url');
var util = require('util');   
var querystring = require('querystring'); 

var appURL = 'http://localhost:5000';
//var appURL = 'http://evening-beach-6294.herokuapp.com';
				
//Mongoose config
//(would like to put this in separate file: http://j-query.blogspot.com/2011/11/mongoose-and-mongohq.html)
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var toDoSchema = new Schema({
   title    : String,
});

mongoose.connect('mongodb://127.0.0.1:27017/data');
mongoose.model('toDo', toDoSchema);
// saves to 'todos' collection in 'data' database rather than todo
var toDo = mongoose.model('toDo');



function add(response, request) {
  console.log("Request handler 'add' was called.");
 	 post_handler(request, function(request_data) {
 	  var todo = new toDo({
 	  		  title : request_data.note
 	  });

 	  todo.save(function(err){
 	  		  console.log("saving"+ request_data.note);
 	  		  if(!err){
 	  		    	console.log('todoItem saved.');
 	  		  }
 	  });
 	 });
 	response.writeHead(301, {'Location':appURL + '/list', 'Expires': (new Date).toGMTString()});
        response.end();
}

function list(response) {

	console.log("Request handler 'list' was called.");
	toDo.find({}, function(err,todos) {
			
			response.writeHead(200, {'Content-Type': 'text/html'});        
			response.write('Todo List');  
			response.write('<h1>ToDo list</h1>');  
			response.write('<ul>'); 
    
    
			todos.forEach(function(todo) {
				response.write('<li>' + todo.title + ' <a href="remove?id='+todo._id+'">remove</a></li>');  ;
			})
		
			var form = ''+
			''+
			''+
			''+
			''+
			'';
			response.end(form);	
		
	});		

	
	
		
}
	
function remove(response, request) {
	console.log("Request handler 'remove' was called.");
	parsedURL = url.parse(request.url, true);
	console.log(' _id to remove ' + parsedURL.query['id']);
	toDo.findOne({_id: parsedURL.query['id']},function(err,docs){
	  console.log('deleting' + docs);  //Remove all the documents that match!
	  docs.remove();
	  docs.save();
	  
	  // 301 permanent redirect to list\
	  response.writeHead(301, {'Location':appURL + '/list', 'Expires': (new Date).toGMTString()});
	  response.end();
	});
}
 
 
function post_handler(request, callback){
    var _REQUEST = { };
    var _CONTENT = '';

    if (request.method == 'POST')
    {
        request.addListener('data', function(chunk)
	{
	    _CONTENT+= chunk;
	});

	request.addListener('end', function()
	{
            _REQUEST = querystring.parse(_CONTENT);
	    callback(_REQUEST);
	});
    };
};

exports.add = add;
exports.list = list;
exports.remove = remove;

The code uses mongoose to connect to MongoDB. I learnt how to use Mongoose from this post.

Aside from the javascript there are a few more files to enable the application to work with Heroku:

Procfile: a file called “Procfile” with no file extension should be added to work with foreman. The foreman section is noted below, but when you enter the command “foreman start”, the foreman process looks for the procfile within the folder and excutes the commands listed. Note the file must be called “Procfile” with a capital P. There is only one line in this file:

web: node index.js

package.json:

{
  "name": "mongoHQ-LocalNotes",
  "version": "0.0.1",
  "dependencies": {
    "express": "2.2.0",
    "mongoose": "2.0.2"
  }
}

package.json contains all the packages that the application uses, such as express and mongoose. This is required by heroku so that it can load the supporting packages when the application is uploaded.

One final thing to mention about the code was that the javascript in the requestHandler.js file contains the config for connecting to MongoDB. This is pointing to a database called ‘data’, but though the collection is called “todo”, for some reason the mongoose driver pluralises this to “todos”. Both the database and collection will be created implicitly when this code runs but if you wish to see the data in the console you must enter the following in a terminal window:

alex@ubuntu:~/NodeProjects/MongoHQLocalNotes$ mongo
MongoDB shell version: 2.0.2
connecting to: test
> use data
switched to db data
> db.todos.find()
{ "title" : "pick up washing", "_id" : ObjectId("4ee7c23b889913d90c000001") }
{ "title" : "do this", "_id" : ObjectId("4ee9b1996541801e08000010") }
{ "title" : "do that", "_id" : ObjectId("4ee9b22306737c2708000011") }
>

so use todos.find() instead of todo.find().

To enable express to work and other packages you have to install npm, which you will call to install each package. You can install npm with this curl command from a terminal window:

curl http://npmjs.org/install.sh | sudo sh

Once this is done you can install express:

npm install express

and mongoose:

npm install mongoose

The final piece of the jigsaw to get all this working locally before deploying to Heroku is to install Foreman. Foreman is a ruby application, so requires ruby to run it. To install ruby, type the following into a terminal window:


alex@ubuntu:~$ sudo apt-get install ruby1.9.1

alex@ubuntu:~$ sudo apt-get install rubygems

Then to install Foreman:

alex@ubuntu:~$ sudo gem install foreman

on the first try, foreman failed to install with the error message:

errors with Invalid gemspec in [/var/lib/gems/1.8/specifications/foreman-0.26.1.gemspec]: invalid date format in specification: “2011-11-10 00:00:00.000000000Z”
Invalid gemspec in [/var/lib/gems/1.8/specifications/term-ansicolor-1.0.7.gemspec]: invalid date format in specification: “2011-10-13 00:00:00.000000000Z”

The solution was to edit gemspec files by opening nautilus (Ubuntu’s explorer application) with root privileges; Hold down Alt+F2 then type “gksudo nautilus” and browse to, then edit (remove “.000000000Z”) and save the .gemspec files.

The command sudo gem install foreman should now install Foreman. To test this browse to the folder containg the Procfile created earlier and enter the following command:

foreman start

The output should be


19:36:31 web.1 | started with pid 4063
19:36:32 web.1 | Server has started on port 5000

or similar…

4. Setup MongoHQ

The next job was to get the app talking to a remotely hosted database. For this I used MongoHQ. Setting up MongoHQ is fairly simple. All you need to do is sign up, create a database (I created a database called “data”) and then go to the Database Info tab. Just make a note of the Mongo URI such as mongodb://:@environment.mongohq.com:12345/data , which can then be used in the mongoose.connect call in requestHandler.js. You don’t need to create collections as this can be created implicitly through the ToDo app. To test the MongoHQ database, just replace the url to localhost with the Mongo URI supplied by MongoHQ in the mongoose.connect call.

5. Deploy to Heroku

By this time I had all the aspects of the application in place. The final job was to push it onto Heroku. This post from Heroku describes the whole process. Before you put anything onto heroku, you need to register with them first. The next step is to install the heroku toolbelt, which can be done through some commands on your terminal:

>sudo apt-add-repository 'deb http://toolbelt.herokuapp.com/ubuntu ./'
>curl http://toolbelt.herokuapp.com/apt/release.key | sudo apt-key add
>sudo apt-get update
>sudo apt-get install heroku-toolbelt

once this install is complete you can start using heroku commands from the terminal.

Everything is in place to deploy to heroku using the cedar stack. Below is the output from the terminal when deploying my ToDo list app to heroku:

alex@ubuntu:~/NodeProjects/MongoHQLocalNotes$ git init
Initialized empty Git repository in /home/alex/NodeProjects/MongoHQLocalNotes/.git/
alex@ubuntu:~/NodeProjects/MongoHQLocalNotes$ git add .
alex@ubuntu:~/NodeProjects/MongoHQLocalNotes$ git commit -m "init"
[master (root-commit) 644f613] init
Committer: Alex
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:

git config --global user.name "Your Name"
git config --global user.email you@example.com

After doing this, you may fix the identity used for this commit with:

git commit --amend --reset-author

15 files changed, 477 insertions(+), 0 deletions(-)
create mode 100644 Procfile
create mode 100644 Procfile~
create mode 100644 index.js
create mode 100644 index.js~
create mode 100644 model.js
create mode 100644 model.js~
create mode 100644 mongoose.js
create mode 100644 mongoose.js~
create mode 100644 package.json
create mode 100644 package.json~
create mode 100644 requestHandlers.js
create mode 100644 requestHandlers.js~
create mode 100644 router.js
create mode 100644 server.js
create mode 100644 server.js~
alex@ubuntu:~/NodeProjects/MongoHQLocalNotes$ heroku create --stack cedar
Creating evening-beach-6294... done, stack is cedar
http://evening-beach-6294.herokuapp.com/ | git@heroku.com:evening-beach-6294.git
Git remote heroku added
alex@ubuntu:~/NodeProjects/MongoHQLocalNotes$ git push heroku master
Warning: Permanently added the RSA host key for IP address '50.19.85.132' to the list of known hosts.
Counting objects: 19, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (17/17), done.
Writing objects: 100% (19/19), 3.93 KiB, done.
Total 19 (delta 6), reused 0 (delta 0)

-----> Heroku receiving push
-----> Node.js app detected
-----> Fetching Node.js binaries
-----> Vendoring node 0.4.7
-----> Installing dependencies with npm 1.0.94

> mongodb@0.9.6-7 install /tmp/build_ewue4f2tjx88/node_modules/mongoose/node_modules/mongodb
> bash ./install.sh

================================================================================
= =
= To install with C++ bson parser do =
= the parser only works for node 0.4.X or lower =
= =
================================================================================
Not building native library for cygwin
mongoose@2.0.2 ./node_modules/mongoose
├── colors@0.5.0
├── hooks@0.1.9
└── mongodb@0.9.6-7
express@2.2.0 ./node_modules/express
├── mime@1.2.4
├── qs@0.4.0
└── connect@1.8.3
Dependencies installed
-----> Discovering process types
Procfile declares types -> web
-----> Compiled slug size is 7.9MB
-----> Launching... done, v4
http://evening-beach-6294.herokuapp.com deployed to Heroku

To git@heroku.com:evening-beach-6294.git
* [new branch] master -> master
alex@ubuntu:~/NodeProjects/MongoHQLocalNotes$ heroku ps
Process State Command
------- ---------- -------------
web.1 up for 10s node index.js
alex@ubuntu:~/NodeProjects/MongoHQLocalNotes$ heroku logs
2011-12-16T23:53:13+00:00 heroku[slugc]: Slug compilation started
2011-12-16T23:53:19+00:00 heroku[api]: Config add PATH by lalexgraham@hotmail.com
2011-12-16T23:53:19+00:00 heroku[api]: Release v3 created by lalexgraham@hotmail.com
2011-12-16T23:53:19+00:00 heroku[api]: Deploy 1663f77 by lalexgraham@hotmail.com
2011-12-16T23:53:19+00:00 heroku[api]: Release v4 created by lalexgraham@hotmail.com
2011-12-16T23:53:19+00:00 heroku[web.1]: State changed from created to starting
2011-12-16T23:53:20+00:00 heroku[slugc]: Slug compilation finished
2011-12-16T23:53:22+00:00 heroku[web.1]: Starting process with command `node index.js`
2011-12-16T23:53:22+00:00 app[web.1]: Server has started.
2011-12-16T23:53:22+00:00 heroku[web.1]: Error R11 (Bad bind) -> Process bound to port 8888, should be 14296 (see environment variable PORT)
2011-12-16T23:53:22+00:00 heroku[web.1]: Stopping process with SIGKILL
2011-12-16T23:53:23+00:00 heroku[web.1]: State changed from starting to crashed
2011-12-16T23:53:23+00:00 heroku[web.1]: State changed from crashed to created
2011-12-16T23:53:23+00:00 heroku[web.1]: State changed from created to starting
2011-12-16T23:53:24+00:00 heroku[web.1]: Process exited
2011-12-16T23:53:26+00:00 heroku[web.1]: Starting process with command `node index.js`
2011-12-16T23:53:26+00:00 app[web.1]: Server has started.
2011-12-16T23:53:27+00:00 heroku[web.1]: Error R11 (Bad bind) -> Process bound to port 8888, should be 20500 (see environment variable PORT)
2011-12-16T23:53:27+00:00 heroku[web.1]: Stopping process with SIGKILL
2011-12-16T23:53:28+00:00 heroku[web.1]: State changed from starting to crashed
2011-12-16T23:53:28+00:00 heroku[web.1]: Process exited
2011-12-16T23:55:43+00:00 heroku[api]: Scale to web=1 by lalexgraham@hotmail.com
2011-12-16T23:59:34+00:00 heroku[slugc]: Slug compilation started
2011-12-16T23:59:39+00:00 heroku[api]: Deploy f5f5fdb by lalexgraham@hotmail.com
2011-12-16T23:59:39+00:00 heroku[api]: Release v5 created by lalexgraham@hotmail.com
2011-12-16T23:59:40+00:00 heroku[web.1]: State changed from crashed to created
2011-12-16T23:59:40+00:00 heroku[web.1]: State changed from created to starting
2011-12-16T23:59:40+00:00 heroku[slugc]: Slug compilation finished
2011-12-16T23:59:41+00:00 heroku[web.1]: Starting process with command `node index.js`
2011-12-16T23:59:42+00:00 app[web.1]: Server has started.
2011-12-16T23:59:42+00:00 heroku[web.1]: State changed from starting to up

….so all thats left is to now browse to the url provided by Heroku (in this case http://evening-beach-6294.herokuapp.com, and you should see your app on a public url. Now have a cup of tea to celebrate:)

EDIT

I have since done the following…

1.amended the source code, adding a meta tag to the html in the output on requestHandlers.js

uploaded source code to github at https://github.com/lalexgraham/ToDoList

2.uploaded a revised version of the code to Heroku and github

To update both github and heroku you need to enter the following commands whilst in the terminal and browsed to the folder containing the code:

git add .
git commit -m “commit message”
git push heroku master (for heroku)
git push origin master (for git hub)