Mean Stack Tutorial

A tutorial on using the MEAN framework for developing web applications

Created by Mohammed Hussain, Jeff Sallans, Dave Farinelli

Presentation: http://xby2.github.io/mean-stack-presentation

What is the MEAN Stack?

JavaScript frontend and backend web application setup. It uses:

  • NoSql database
  • Web application framework
  • Frontend databinding framework
  • Server-side JavaScript environment

Why MEAN Stack?

Setting up MongoDB Server

1. Create default data directory at C:\data\db

2. Run the following commands:

							
cd {mongoDB_installation}/Server/3.0/bin
mongod
							
						

Should display 'listening on port 27017'

Writing an app from scratch

Navigate to site directory

Install Node package Express generator to allow for quickly generating a new Express site.

Run the command:

							npm install -g express-generator
						

Run the express command to generate a new Express site using ejs client-side templates.

Run the command:

							express --ejs site-name
						
Navigate into new directory

Install all node packages currently defined in new site package file.

Run the command:

							npm install
						

Install mongoose Node package to connect to running MongoDB instance.

Run the command:

							npm install --save mongoose
						
Make a new directory for your models
Open up file ./app.js, and add this line to the top to add mongoose instance:
							var mongoose = require("mongoose");
						
Add the following code to have mongoose connect to your local MongoDB server:
							
require("./models/Posts");
mongoose.connect('mongodb://localhost/peanutgallery');
						
Create a new file ./models/Posts.js
Add code to Posts.js to create MongoDB schema
							var mongoose = require("mongoose");
var PostSchema = new mongoose.Schema({
  title: String,
  body: String,
  timestamp: Date
});
mongoose.model("Post", PostSchema);
						
Open up ./routes/index.js
Add mongoose and Post to the route file
							var mongoose = require("mongoose");
var Post = mongoose.model("Post");
						
Create GET route for retrieving models:
							router.get("/posts", function(req, res, next) {
  Post.find(function(err, posts) {
    if (err) {
      return next(err);
    }

    res.json(posts);
  });
});
						
Create POST route for posting models:
							router.post("/posts", function(req, res, next) {
  var post = new Post(req.body);

  post.save(function(err, post) {
    if (err) {
      return next(err);
    }

    res.json(post);
  });
});
						
Start site:
							npm start
						
Navigate to http://localhost:3000/posts

Angular

Add angular code to ./public/scripts/angular.min.js
Create new files:
./public/javascripts/pgapp.js
Add head and body to index.ejs
							
<html>
  <head>
    <title>say something</title>
    <script src="/javascripts/angular.min.js"></script>
    <script src="/javascripts/pgapp.js"></script>
  </head>
  <body>
  </body>
</html>
							
						
Create a new angular app in pgapp.js
							
(function() {
  "use strict";

  var app = angular.module("peanutGallery", []);
})();
							
						
Add ng-app and a quick demo to index.ejs
							
<body ng-app="peanutGallery">
  {{ 1 / (1 / (1 - (3/4))) }}
</body>
							
						
Add a new controller to pgapp.js
							"use strict";

var app = angular.module("peanutGallery", []);

app.controller("mainController", [
  "$scope",
  "$http",
  function($scope, $http) {
    $scope.test = 1 / (1 / (1 - (3/4)));
  }
]);

						
Add controller to the body
							
<body ng-app="peanutGallery" ng-controller="mainController">
  {{ test }}
</body>
							
						
Add ability to retrieve posts in controller (in pgapp.js)
							$scope.posts = [];
$scope.newPost = "";

$scope.init = function() {
  $scope.getAllPosts();
}

$scope.getAllPosts = function() {
  return $http.get("/posts").success(function(data) {
    angular.copy(data, $scope.posts);
  });
};
						
Add ability to create posts in controller (in pgapp.js)
							$scope.createNewPost = function() {
  var tempPost = {
    title: $scope.posts.length + 1 + "",
    body: $scope.newPost,
    timestamp: new Date()
  };

  $http.post("/posts", tempPost).success(function(data) {
    $scope.posts.push(data);
  });

  $scope.newPost = "";
};

$scope.init();
						
Display and create posts in index.ejs
							<div class="title">
  <h1>The Peanut Gallery</h1>
</div>
<div>
  <input placeholder="say something" ng-model="newPost" />
  <button ng-click="createNewPost()">Submit</button>
</div>
<div ng-repeat="post in posts">
  <div>
    <h3>{{ post.title }}</h3>
    <p>{{ post.body }}</p>
    <i>{{ post.timestamp }}</i>
  </div>
</div>
						
Anndddd we're done.

ADK

Additional domain knowledge

Gulp vs Grunt

Code vs config files

Go with Gulp

https://medium.com/@preslavrachev/gulp-vs-grunt-why-one-why-the-other-f5d3b398edc4

NPM vs Bower

NPM - Resolves dependencies in a nested structure (used on the backend for easier setup/deploy)

Bower - Resolves dependencies in a flat structure (used on the frontend to keep client code light)

http://stackoverflow.com/questions/18641899/what-is-the-difference-between-bower-and-npm

Further Research