MEAN Stack – A Quick Start Guide

mean_header

By Mathew Carella

The MEAN stack has been getting a lot of publicity lately. In case you haven’t heard about it yet, MEAN stands for MongoDB, Express, Node.js and AngularJS. This article is intended to serve as a quick guide to help you get started developing with the MEAN stack. We won’t go into great detail about what each of the technologies are, instead sticking to how to set up a typical MEAN stack.

To get started, of course, you’ll need to have Node.js and ExpressJS installed on your environment. Just follow the instructions on their respective sites if you don’t have these already and then come back and continue here.

Installing MongoDB

To get started installing the MongoDB NoSQL database, follow these steps.

  1. Download it
  2. Unzip it into a folder (ex. myfolder\mongodb)
  3. Navigate into the directory: myfolder\mongodb\bin
  4. Open a command prompt here and run the following command: mongod --dbpath data
  5. Install Mongoose by opening a command prompt and typing: npm install mongoose

Setting Up Express

Express is a popular web application framework for Node.js. To get it installed, follow these steps:

  1. Navigate into a directory: myfolder
  2. Install Express by opening a new command prompt and typing: npm install -g express
  3. Create a new Express app typing the command: express --sessions myapp
  4. Navigate into the directory: myfolder\myapp
  5. Open a new command prompt here and type: npm install
  6. Create a server.js file the directory: myfolder\myapp

Setting Up Server.js

Next we’ll create a simple Node.js server. Remember that anytime you modify the server.js file, you will need to restart it to see your changes working. The following are the contents of our server.js file:

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

app.get('/ping', function(req, res) {
    res.send({ping:'hello this is server and I am alive!'});
});

app.get('/ping/:id', function(req, res) {
    res.send({ping:'hello this is server and I am got '+req.params.id});
});

app.listen(3000);
console.log('Listening on port 3000...');

Once you’ve created a server.js file like the one above, follow these steps to get it running.

  1. Navigate into your application directory: myfolder\myapp
  2. Within the command prompt, type: node server.js (this will start the server)

Testing the Server

To make sure your server is up and is doing its work, query your simple API route. To do this, I found really useful Chrome plugin called Postman. You can see the results of my tests using Postman in the screenshots below.

postman1

postman2

Creating a Database

  1. Open a new command prompt and navigate into the folder: myfolder\mongodb\bin, and type the command: mongo
  2. Create a new database typing use in the command prompt (ex. use mydatabase)

Interacting with Mongoose

Next let’s modify our server.js as shown here so that it can interact with MongoDB using Mongoose.

var express = require('express');
var app = express();
var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/mydatabase');
var db = mongoose.connection;

app.listen(3000);
console.log('Listening on port 3000...');

You can also add some control to make sure your MongoDB works fine:

db.on('error', function callback () {
  console.log("Connection error");
});

db.once('open', function callback () {
  console.log("Mongo working!");
});

Inserting and Querying Data from MongoDB

It’s now time to make things a little more complex. Let’s edit the server file again. If you don’t understand the code, don’t worry, I am going to explain all the lines later in the post.

var express = require('express');
var app = express();
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var Factory = require("./module.factory.js");

mongoose.connect('mongodb://localhost/mydatabase');
var db = mongoose.connection;

var factory = new Factory(Schema,mongoose);
factory.createSchemas();
factory.insertPeople();

app.get('/ping', function(req, res) {
    res.send({ping:'hello this is server and I am alive!'});
});

app.get('/ping/:id', function(req, res) {
    res.send({ping:'hello this is server and I am got '+req.params.id});
});

app.get('/person/hektor', function(req, res) {
     var resp = factory.getPerson({name:'hektor'},res);
});

app.listen(3000);
console.log('Listening on port 3000...');

Let’s have a closer look to this code:

var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var Factory = require("./module.factory.js");

…and this other one:

var factory = new Factory(Schema,mongoose);
factory.createSchemas();
factory.insertItems();
factory.getItem({name:'hektor'});

First of all you need to be aware that “everything in Mongoose starts with a Schema. Each schema maps to a MongoDB collection and defines the shape of the documents within that collection.” That’s why I’ve created a factory (module.factory.js) to insert some data in MongoDB and to retrieve them from the entire collection. How do we create a factory?

module.factory.js

var Factory = function(Schema,mongoose) {

	this.Schema = Schema;
	this.mongoose = mongoose;
	this.Item = null;

	this.createSchemas = function() {

		PersonSchema = new this.Schema({
			name: String,
			surname: String, 
			age: Number

		});

		this.Person = mongoose.model('Person',PersonSchema);
	}

	this.insertPeople = function() {

		var hektor = new this.Person({
			name: 'hektor',
			surname: 'baboden',
			age: 35

		}); 

		var john = new this.Person({
			name: 'john',
			surname: 'johannis',
			age: 55

		}); 

		hektor.save();
		john.save();
	}

	this.getPerson = function(query,res) {

		this.Person.find(query,function(error,output) {
			res.json(output);
		});
	}
}

module.exports = Factory;

As you might expect, the method createSchemas() allows me to create a new schema that maps to my data structure. Once I’ve created a schema, I can insert data in my MongoDB, in this case using a method called insertPeople().

Putting It All Together

Finally, we need to put all the pieces together to make it work. Let’s call an API that queries MongoDB to retrieve some data. To make this happen we need to edit the server.js file as follows:

var express = require('express');
var app = express();
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var Factory = require("./module.factory.js");

mongoose.connect('mongodb://localhost/mydatabase');
var db = mongoose.connection;

var factory = new Factory(Schema,mongoose);
factory.createSchemas();
factory.insertPeople();

app.get('/ping', function(req, res) {
    res.send({ping:'hello this is server and I am alive!'});
});

app.get('/ping/:id', function(req, res) {
    res.send({ping:'hello this is server and I am got '+req.params.id});
});

app.get('/person/hektor', function(req, res) {
     var resp = factory.getPerson({name:'hektor'},res);
});

app.listen(3000);
console.log('Listening on port 3000...');

Below is a screenshot of the result of this call within Postman:

postman3

Adding the UI

Now that we have our API along with a backend service that sends JSON data to my application, we want to navigate to a page to and see the data displayed nicely on it?. To do this, we just have to modify server.js again:

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

app.get('/', function (req, res) {
	res.render('index',{ title : 'Home' })
})

The prior line allow us to display our index.html page by navigating the the URL: http://localhost:3000/. Thus, the final version of our basic server.js file will be as follows:

var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var Factory = require("./module.factory.js");

mongoose.connect('mongodb://localhost/mydatabase');
var db = mongoose.connection;

var factory = new Factory(Schema,mongoose);
factory.createSchemas();
factory.insertPeople();

app.get('/ping', function(req, res) {
    res.send({ping:'hello this is server and I am alive!'});
});

app.get('/ping/:id', function(req, res) {
    res.send({ping:'hello this is server and I am got '+req.params.id});
});

app.get('/person/hektor', function(req, res) {
     var resp = factory.getPerson({name:'hektor'},res);
});

app.get('/', function (req, res) {
	res.render('index',{ title : 'Home' })
})

app.listen(3000);
console.log('Listening on port 3000...');

Angular

It’s now AngularJS time. We need to create an app.controller.js file. Below is a simple controller example that will ask for some data, using the simple API we defined earlier:

var myApp =  angular.module('myApp',[]); 

myApp.controller('myAppController',['$scope', '$http', function ($scope, $http, myAppService) { 

  	$scope.people = [];

    $scope.init = function() { 

    	$http.get('http://localhost:3000/person/hektor').then(function(result) { $scope.people = result.data; });
    } 

    $scope.init(); 

}]);

The controller makes a get API call to retrieve some data. Next, we need to modify the index.html page.

<!DOCTYPE html>
<html ng-app="myApp">

	<head>
		<title>App Title</title>
	</head>

	<body ng-controller="myAppController">

		<div ng-repeat="person in people">
			{{person.name}} {{person.surname}} {{person.age}}
        </div>

	</body>

	<script src="js/lib.angular.js"></script>
	<script src="js/app.controller.js"></script>

</html>

Lastly, all we only need to browse to the localhost address to see page displayed on the screen!

Where to Go From Here

Obviously, our application was extremely simple, but it allowed us to get everything installed, set up and working and to understand some of the basics of the MEAN stack. If you’d like to explore further, I suggest the ongoing series by Gabriel Cirtea on creating an RSS feed reader using the MEAN stack:

This article was originally published at http://blog.mathewdesign.com/2014/04/11/getting-started-with-mean-stack/

Modern Web Newsletter

Subscribe to receive the Modern Web tutorials, sent out every second Wednesday.

  • http://pointsource.us Steven

    I can also recommend looking at http://meanjs.org (not mean.io) to get started quickly.

  • Pingback: MEAN Stack | Node.js Israel

  • Luc Step

    When I try to install express, using the provided command, as root on an Ubuntu Linux (“npm install express -g”), it installs correctly (in /usr/lib/node_modules/express), but I don’t get any ‘express’ executable. It is the 4.0.0 version that gets installed. Has this been removed in that version or did I do something wrong?

    • https://fantasywinlosedraw.com Josh Oldham

      Luc, I had the same issue. Trying npm install express-generator -g worked for me. Not sure if it is related, but in the next command I had to omit the –sessions and just write express myApp.

      Also, another gotcha for me was that at the end the index.html file has to be in the public directory. Perhaps obvious, but it cost me a bit of time

    • https://github.com/brunanatal Bruna

      You need to install it local (inside your project’s folder) in order to have the executable express. Just “npm install express”, this -g belongs to a global installation.

    • http://cuthalion.ca Jon Barson

      Luc,
      As per the express Github page here: https://github.com/visionmedia/express#quick-start The express generator needs to be installed separately. npm install -g express-generator will install the generator for express.

      Jon

  • Ronen

    Very helpful article for starters. Thanks.

  • Aurelien

    Hi,
    nice article,
    but isn’t it better for the angular part to use $resource for the exchange with the server ?

    • http://obdstudios.com Jedediah Smith

      In AngularJS it really depends on what you are doing whether you should use $resource. In this tutorial where they are just getting something going to show you it works $http makes a lot of sense. $http also allows for more customized interfacing and for using non-RESTful API calls. That being said from my experience the MEAN stack really lends itself to using REST so generally you will want to use something like $resource though in my experience if you are making a moderately complex RESTful API which allows for sub-resources you are better off using something like Restangular and if it is a complex API you will probably want to create some real models which means either have to add lots of custom coding in which case it might make since to use any of the three (depending on what makes it complex and how you want you models to work) or use something like Breeze or I have even heard of using Backbone for your models.

  • Pingback: Weekend reading list | Daniil's Blog

  • http://none Emma

    I can’t get this working and I don’t know what am I doing wrong. The pings work just fine, I created the module.factory.js file and made sure it’s saved in the same directory as server.js, but when I try to connect to http://localhost:3000/person/hektor all I get is a “Cannot GET /person/hektor” message. I’ve carefully checked all my code to make sure I don’t have any typos. Any idea what could be wrong? Mongod is running fine and I confirmed my new database exists by running “show dbs”.

    • http://- Michael

      I have seen this error before in other MEAN apps. The text above says:

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

      app.get(‘/’, function (req, res) {
      res.render(‘index’,{ title : ‘Home’ })
      })
      The prior line allow us to display our index.html page by navigating the the URL: http://localhost:3000/. Thus, the final version of our basic server.js file will be as follows:

      Express makes a “shortcut” for files in the “static ” folder, so that if you change your URL from:

      http://localhost:3000/person/hektor

      to

      http://localhost:3000/hektor.html

      that may work. Also if you rename the hektor file to index.html that may also work.

      I don’t have time to assemble all of this code demo into a working app to confirm this myself, but that is very likely where the “Cannot GET /person/hektor” message” is coming from. I have seen that exact same syntax in my own apps, and that was the solution.

      NOTE: there is some additional confusion for me about the above demo code because the “static” directory seems to have been named “public” or “person” in different places, so you may need to fuss around with the name of the directory in which the hektor files lives.

      Hope this helps.

    • http://- Michael

      I just noticed that Josh Oldham made a similar comment in a comment thread started by Luc above, Josh said:

      “at the end the index.html file has to be in the public directory.”

  • http://twiiter.com/arcseldon arcseldon

    Thanks for sharing this. I have built out full enterprise MEAN apps, and to date the single best resource for learning MEAN end to end is the course on PluralSight.com by Joe Eames. That course alone gives you enough to start being commercially productive.
    http://pluralsight.com/training/Courses/TableOfContents/building-angularjs-nodejs-apps-mean

Top