JavaScript
Article

Introduction to the MEAN Stack

By Aldo Ziflaj

It was a long time ago since the acronym LAMP (Linux Apache MySql PHP) was created. Today another very common stack is the MEAN stack. Probably not all of you know what that the acronym “MEAN” stands for, so let’s start with the basic. MEAN stands for MongoDB, Express, AngularJS and Node.js. It deals with a full stack JavaScript solution for building websites and web applications. From the database to the back-end code and the front-end code, everything is written using JavaScript. In case you aren’t familiar with the technologies used by the MEAN stack, you can find a short introduction about these technologies in the following section.

You can find the whole source code for this article on GitHub. Feel free to fork it and play around with it.

MEAN

M stands for MongoDB, the world’s leading NoSQL database. That’s a kind of document type database that stores its data into a JSON-like formatted binary file called BSON (Binary JSON). It’s easy to use, and for JavaScript developers it should be as simple as working with JSON.

E stands for Express, a lightweight, minimalist framework built for Node.js. It’s been created for web applications and APIs, and comes with a myriad of HTTP facilities for the developer.

A stands for AngularJS, the Model-View-Whatever JS framework build by Google. AngularJS makes API consuming as simple as it could be, so using it as the client-side of MEAN is very helpful for every developer. Moreover, AngularJS is optimized for mobile development, so by using the same code base on the browser, you have already built a mobile app for the web application you’re developing.

N stands for Node.js, the foundation of Express. It runs on Chrome’s V8 engine and is capable of non-blocking, event-driven I/O. The Node.js application will handle multiple requests on a single service without them blocking each-other (hence non-blocking).

Prerequisites

Before starting, make sure you have MongoDB and Node.js installed. Node.js comes with a package manager called npm, which we’ll use for package (dependency) management. If you are experienced with PHP, npm is the equivalent of Composer, while the equivalent of Packagist would be npmjs.org. There you’ll find almost an equivalent package for every PHP package you’re using, which makes the transition to a Node.js web app simpler.

The First Express Server

First of all, run the following command on your terminal:

npm init

After answering the questions, it’ll create a package.json file with the necessary information. Here is mine:

{
  "name": "sp-mean",
  "version": "0.1.0",
  "description": "An introduction to MEANstack for SitePoint",
  "main": "server.js",
  "scripts": {
    "start": "node ./server"
  },
  "author": "Aldo Ziflaj",
  "license": "None"
}

The "main": "server.js" means that the main file that will be executed on the server is server.js.

As the second step, let’s add express as dependency by executing the command:

npm install express --save

This will add a node_modules directory where the dependencies are stored. Keep in mind that you should neglect this folder from version control.

At this point, the next step is to write the Express app that will act as a server:

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

app.get('/', function(req, res) {
    res.send("Hello from Express");
});

app.listen(3000, function() {
    console.log("Server ready. Listening on port 3000");
});

By executing npm start it’ll bring the server up on http://localhost:3000 and will send Hello from Express when you browse to index.

Using MongoDB

In order to use MongoDB from the Express app, we’re going to use a package from npmjs.com. There is a long list of packages you could use, including mongodb, monk, or mongoose. For this example, I’ll use monk. To start its installation, run the command:

npm install monk --save

And then, start the Mongo console by executing

mongo

Now, insert some data into Mongo by executing:

use starwars;

db.character.insert({
    name: "Luke", 
    surname: "Skywalker", 
    side: "Light", 
    weapon: "Lightsaber"
});

db.character.insert({
    name: "Yoda",
    side: "Light",
    weapon: "Lightsaber"
});

db.character.insert({
    sith_name: "Vader",
    side: "Dark",
    weapon: "Lightsaber"
});

db.character.insert({
    sith_name: "Sidious",
    side: "Dark",
    weapon: "Force lightning"
});

This should be enough for our collection. As you can see, we don’t have to set the same keys for all the records: Luke and Master Yoda don’t have a sith_name. This is legit in MongoDB since it is schema-less; as long as you’re inserting legit JavaScript objects you are good to go.

Now we can use monk to get the data from the database and show it to the user.

Firstly, require the dependency at the top of server.js:

var monk = require('monk');

Now get a reference to the collection we created before:

var swChars = monk('localhost:27017/starwars').get('character');

This might as well be written as:

var db = monk('localhost:27017/starwars');
var swChars = db.get('character');

The first line of code gives you a reference to the database (starwars) in case you need to use more than one collection. Next, we get() a reference to the collection we’re using, the character collection.

Now, let’s give the user a whole list of characters we’re storing when he browses to /character:

app.get('/character', function (req, res) {
  swChars.find({}, function (err, docs) {
    if (err == null) {
      res.json(docs);
    } else {
      console.log(err);
    }
  });
});

By using the find() function, we query the collection referred by swChars. The first parameter are the rules of querying, but since we’re showing all the characters, I put an empty JavaScript object there. The second parameter is a callback function executed after the records have been fetched from the database collection.

We can show some of the records, let’s say only the Jedi knights, by querying by side:

app.get('/jedi', function (req, res) {
  swChars.find({side: "Light"}, function (err, docs) {
    if (err == null) {
      res.json(docs);
    } else {
      console.log(err);
    }
  });
});

Monk covers plenty of functions to help you use a Mongo database. Check its GitHub repository for more information about how to use monk.

AngularJS in the Front-end

Building the back-end has been simple. Not too much boilerplate code, simple API routes and really simple data persisting. Now, to show that information to the user, we’re going to use AngularJS.

Use Bower to get AngularJS:

# create a bower.json file to store dependencies
bower init
bower install angular#1.4.3 --save

For the client-side, create these files/folders:

assets/js/ngapp.js
assets/js/controllers
assets/js/services

The first one is the base AngularJS application we’re building. The second one is the directory where the controllers will stay, and the third one is the directory where services (such as factories) will stay. To create the base Angular application, put this on ngapp.js:

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

Don’t forget to include this in the index.html file.

Now, to fetch the data from the back-end API, we’ll create a factory. Create a file called StarWarsFactory.js in the services folder:

app.factory('StarWarsFactory', function ($http) {
  return {
    characters: function () {
      return $http.get('/character');
    },

    jedi: function () {
      return $http.get('/jedi');
    }
  }
});

Now to use this, add a simple controller, called MainCtrl.js:

app.controller('MainCtrl',function(StarWarsFactory) {
  var self = this;
  StarWarsFactory.characters().success(function(data) {
    self.charList = data;
  });
});

Include all of these JS files in the index.html file and put this div to show the data fetched from the server:

<div ng-controller="MainCtrl as m">
  <ul>
    <li ng-repeat="item in m.charList">
      <span ng-if="item.side === 'Light'">
        {{item.name}} {{item.surname}} uses {{item.weapon}}
      </span>

      <span ng-if="item.side === 'Dark'">
        Darth {{item.sith_name}} uses {{item.weapon}}
      </span>
      </li>
  </ul>
</div>

Finally, to serve this from the Express app, you have to delete that / route that shows only “Hello from Express” and put this piece of code instead of that:

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

app.get('/', function (req, res) {
  res.sendFile(path.join(__dirname + "/index.html"));
});

When you browse to localhost:3000, you’ll see the list of the characters and their weapon of choice.

Conclusions

In this article we’ve learnt how to build a simple application using a stack called MEAN. We used Mongo to store the data as JavaScript objects, Express in the backend to build the API and AngularJS in the frontend as the client of the API.

You can find the whole source code for this article on GitHub. Feel free to fork it and play around with it.

Finally, you should know that there are a lot of generators for MEAN. In this article, I thought of not using a generator to make it simpler for complete beginners to get into MEAN. If you are more experienced with MEAN, check out any generator such as mean.io, the Yeoman generator or even the Express generator and use them in your project.

  • KungFuLambChops

    Gotta include ng-app declaration in the html element in index.html:

    • http://CareersReport.com Carol Ospina

      ì want to guíde! you to amazíng online work opportunity.. 3-5 h of work a day.. payment at the end of each week.. performance dependíng bonuses…earnings of six to nine thousand dollars /month – merely few hours of your free time, a computer, most elementary familiarìty wìth www and trusted web-connection is what is needed…learn more by headìng to my page

    • http://aziflaj.github.io/ Aldo Ziflaj

      Yeah, I forgot to say that, but must be clear for most people with some basic experience with AngularJS. But you’re right.

      • http://careersreport.com Susan Grant

        I need to guide you to fantastic online freelancing opportunity… 3 to 5 h of work /a day… Weekly paycheck… Bonus opportunities…Payscale of $6k to $9k /month… Just several hrs of your free time, a pc, basic knowing of Internet and trusted internet-connection is what is& required…Get more information by visiting my disqus^profile

      • http://careersreport.com Eloise Craven

        I will show excellent internet job opportunity… three-five hrs of work /a day… Payment at the end of each week… Bonuses…Payment of 6-9 thousand dollars /a month… Merely several hrs of spare time, desktop or laptop, most basic knowing of web and dependable internet connection) is what is needed…Get more information by visiting my page

      • http://careersreport.com Eloise Craven

        I will show excellent internet job opportunity… three-five hrs of work /a day… Payment at the end of each week… Bonuses…Payment of 6-9 thousand dollars /a month… Merely several hrs of spare time, desktop or laptop, most basic knowing of web and dependable internet connection) is what is needed…Get more information by visiting my page

  • Letusak

    beware that angular 1.x is not going to be compatible with 2.0 , so if you pal to use it, keep this in mind-1.x apps wont be able to upgrade without significant rewrite

    • http://callmenick.com Nick Salloum

      Angular 1.x will be supported for quite some time though, and rumour has it that the Angular camp will be doing some major work to facilitate easy upgrading to 2.0. Fingers crossed!

    • mbokil

      This has changed. 1.5 will have components so you can upgrade a lot easier to 2. Also they are releasing an upgrade tool too. I would suggest looking at using components instead of directives using 1.5 and you will be fine. RC 1 of 1.5 is out so it should be stable soon.

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in JavaScript, once a week, for free.