Thursday 11 July 2013

Node.js, Express and Mongoose

Start with the Express project

I created a new copy of the Express project from the previous tutorial, source of which you can find on GitHub.
This has got our simple route and single page of info, but the data list for the teams is hard-coded as a JSON object in the ‘routes/index.js’ file.

Install Connect and Mongoose

The easiest way to do this is to use the package.json file in the root of the project and npm. This method allows you to install all of the modules you need at once, or you can add some in later, like we are doing now. This is a useful habit to get in to.
Opening up the package.json file you should see something like this:
1{
2 "name""application-name",
3 "version""0.0.1",
4 "private"true,
5 "scripts": {
6  "start""node app"
7 },
8 "dependencies": {
9  "express""3.0.0rc5",
10  "jade""*"
11 }
12}
We are going to add a couple of lines to the ‘dependencies’ section to include Connect and Mongoose, so that it now looks like this:
1{
2 "name""application-name",
3 "version""0.0.1",
4 "private"true,
5 "scripts": {
6  "start""node app"
7 },
8 "dependencies": {
9  "express""3.0.0rc5",
10  "jade""*",
11  "connect""*",
12  "mongoose""*"
13 }
14}
Save this file and open a terminal prompt at the project folder and run:
1npm install
This will read the dependency list from the package.json file and install any new packages into the project.

Setting up the Mongoose connection and defining the data model

In the root directory of the application we’ll create a ‘model’ folder to contain our database connection, schema information and any interactions with it.
In this folder we will start off by creating a file db.js with the following content:
1var mongoose = require( 'mongoose' );
2
3var teamSchema = new mongoose.Schema({
4 country: String,
5 GroupName: String
6});
7mongoose.model( 'Team', teamSchema );
8
9mongoose.connect( 'mongodb://localhost/euro2012' );
Here we are doing four things:
  1. “Requiring” Mongoose so that we can use it
  2. Defining the schema for a team
  3. Building a ‘model’ of this schema, called “Team”
  4. Connecting to the database, in this case a MongoDB database called ‘euro2012′ on the ‘localhost’ server
The schema and model should both be familiar if you’ve seen my Mongoose & Node.js tutorial.

Getting data from the database

In the ‘model’ folder create a file teams.js. We will use this to search the database for teams with a given ‘GroupName’ and return a JSON response. If you had other ‘team’ related queries they could be placed in here – e.g. all data about a given team.
Our file will need an export function that:
  1. Takes a ‘GroupName’ value as a parameter
  2. Takes a callback function as a second parameter
  3. Searches the MongoDB database for teams with the provided ‘GroupName’
  4. Send the database output to the callback function.
We created a “Team.find()” function last time round, so by taking that, bringing in the ‘Team’ model as a local variable and  requiring Mongoose, teams.js should look something like this:
1var mongoose = require('mongoose');
2
3exports.teamlist = function teamlist(gname,callback){
4 var Team = mongoose.model( 'Team' );
5 Team.find({'GroupName':gname}, function (err, teams) {
6  if(err){
7   console.log(err);
8  }else{
9   console.log(teams);
10   callback("",teams);
11  }
12 })// end Team.find
13}// end exports.teamlist

Establish the Mongoose connection

Mongoose is designed to have a reusable connection created on application startup. It also makes sense to only define the schemas once. So as we start our app by calling app.js this is where we need to require db.js. Let’s add it in to the require section at the top of the file, just after requiring Express.
1var express = require('express')
2 , db = require('./model/db')
3 , routes = require('./routes')
4 , http = require('http')
5 , path = require('path');
(Snipped for brevity, keep the rest of the app.js file intact).

Displaying the data on the webpage

When we created the static data version in Express we hardcoded the JSON object into routes/index like so:
1exports.index = function(req, res){
2 var strGroup = "D";
3 res.render('index', {
4  title: 'Test web page on node.js using Express',
5  pagetitle: 'Hello there',
6  group: strGroup,
7  teams: [{"country":"England"},{"country":"France"},{"country":"Sweden"},{"country":"Ukraine"}]
8 });
9};
Replacing this with the MongoDB data via Mongoose is surprisingly easy. We need to:
  1. Require the teams.js model file
  2. Call the ‘teamlist’ export function, sending it:
    1. The ‘GroupName’ of teams we are searching for
    2. The res.render functions as a callback build the page – including the list of teams – when the database query completes
So let’s modify routes/index.js like so:
1var teamdata = require('../model/teams');
2
3exports.index = function(req, res){
4 var strGroup = "D";
5 teamdata.teamlist(strGroup,function(err,teamlist){
6  res.render('index', {
7   title: 'Test web page on node.js using Express and Mongoose',
8   pagetitle: 'Hello there',
9   group: strGroup,
10   teams: teamlist
11  });
12 });
13};
Again, this is very similar code to that used in my earlier Mongoose tutorial, but here the Express res.render() function is a much neater way of building the resulting web page.

See it working

In terminal cd into the root folder for this site and run it by typing
1node app
Head over to localhost:3000 in your browser and you should see something like this:
Testing Mongoose and Express
If you’ve kept the console.log statements in the code, you should see verification of the data being retrieved from the database. Similar to this:
Mongoose confirmation in terminal
So there it is. Mongoose and Express together, greatly simplifying some of the tasks of development in Node.js
Now that we have the building blocks of Node.js, Express, MongoDB and Mongoose in place, next time we’ll start building a web app we can actually use in the real world.

No comments:

Post a Comment