STACK

Intro To The

Ed Atrero

  • Fullstack developer
  • WordPress Plugin Development (photopressplugins.com)
  • LAMP (Linux, Apache, MySQL, PHP)
  • mauris.co -> MEAN

@edatrero

github.com/eatrero

  1. intro

  2. to do app

FULL STACK

Javascript

all javascript
JSON

{"__v":0,
"date":"2014-11-20T01:39:34.964Z",
"item":"drink sculpin",
"_id":"546d46569142b4887382f1c3"}
{"__v":0,
"date":"2014-11-20T01:39:34.964Z",
"item":"drink sculpin",
"_id":"546d46569142b4887382f1c3"}
{"__v":0,
"date":"2014-11-20T01:39:34.964Z",
"item":"drink sculpin",
"_id":"546d46569142b4887382f1c3"}

JAVASCRIPT

  • Most ubiquitous
  • JS runtime is on almost every PC/Smart Phone/Tablet

Javascript IS on the rise

source: http://adambard.com/blog/top-github-languages-2014/

New repos on GitHub by language

CONTEXT SWITCH

MANY HATS

MORE ROLES

FASTER MVP

Javascript resources

  • JavaScript: The Definitive Guide (O'Reilly - Rhino)
  • JavaScript: The Good Parts (Crockford)
  • You Don't Know JS series (https://github.com/getify/You-Dont-Know-JS)

node.js

RUNTIME ENVIRONMENT FOR JAVASCRIPT

MONGO DB

NO SQL DATABASE

WEB FRAMEWORK FOR NODE

ANGULARJS

MVW FRAMEWORK for building spa

MEAN

IN DEPTH

NODEjs

  • Event driven, non-blocking, single threaded
  • Asynchronous programming
  • Huge community (100k modules on npm registry)

Best FOR

  • High I/O
  • Lots of simultaneous connections
  • Single Page Applications

Event driven vs multi-threaded web server

NOT GREAT FOR / CONS

  • Cpu intensive applications (video encoding)
  • Callback hell

further reading

node http server

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World. I am running node.js\n');
}).listen(1337);

example.js

Running the server

% node example.js

INSTALLING NODE (mac os x)

% brew install node

or

PACKAGE.JSON

{
  "name":         "intro-to-mean",
  "main":         "server/server.js",
  "version":      "0.0.1",
  "scripts": {
    "start":      "grunt"
  },
  "dependencies": {
    "body-parser":  "~1.9.2",
    "connect":      "~3.3.3",
    "express":      "~4.5.1",
    "ejs":          "~0.8.5",
    "lodash-node" : "~2.4",
    "mongoose":     "~3.8.19",
  },
  "engines": {
    "node":         "~0.10.32"
  }
}
% npm install

DEPENDENCY MANAGEMENT

1) "Check node_modules into git for things you deploy, such as websites and apps. Do not check node_modules into git for libraries and modules intended to be reused. Use npm to manage dependencies in your dev environment, but not in your deployment scripts."

{
  "name": "A",
  "version": "0.1.0",
  "dependencies": {
    "B": {
      "version": "0.0.1",
      "dependencies": {
        "C": {
          "version": "0.1.0"
        }
      }
    }
  }
}

2) Use NPM Shrinkwrap

package.json
{
  "name": "A",
  "version": "0.1.0",
  "dependencies": {
    "B": "<0.1.0"
  }
}

package B:
{
  "name": "B",
  "version": "0.0.1",
  "dependencies": {
    "C": "<0.1.0"
  }
}

and package C:
{
  "name": "C,
  "version": "0.0.1"
}

Express js

"Fast, unopinionated, minimalist web framework for node."

WHAT IT DOES

  • Express provides a set of tools for easily interacting with HTTP requests and responses 
  • Adds middleware layers and routing to your api.

SINATRA INSPIRED

require 'sinatra'

get '/hi' do
  "Hello World!"
end

ROUTING

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

app.get('/hi', function (req, res) {
  res.send('Hello World!');
})

REVISED HTTP SERVER

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

app.get('/', function (req, res) {
  res.send('Hello World. I am running node.js/express.');
});

http.createServer(app);
http.listen(1337);

MIDDLEWARE

var app = express();

// a middleware with no mount path; 
// gets executed for every request to the app
app.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});

// a middleware mounted on /user/:id; will be 
// executed for any type of HTTP request to /user/:id
app.use('/user/:id', function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});

// a route and its handler function (middleware system) 
// which handles GET requests to /user/:id
app.get('/user/:id', function (req, res, next) {
  res.send('USER');
});

third party middleware

var express = require('express'),
    bodyParser = require('body-parser'),

var app = express();


// load the body parsing middleware
app.use(bodyParser.json());


// my controller middleware
this.create = function(req, res){
  // read in user request in http body
  newTodo.item 	= req.body.item;

  // save newTodo item
};

TEMPLATING

EXPRESS SUPPORTS 14+ templates

app.set('view engine', 'ejs');

app.get('/', function(req, res) {
    res.render('index.ejs');
});
  • Jade -- Haml inspired template engine
  • Haml.js -- Haml implementation
  • EJS -- embedded JavaScript template engine

CALLBACK HELL

ASYNC

async.waterfall([
    function(callback){
        callback(null, 'one', 'two');
    },
    function(arg1, arg2, callback){
      // arg1 now equals 'one' and arg2 now equals 'two'
        callback(null, 'three');
    },
    function(arg1, callback){
        // arg1 now equals 'three'
        callback(null, 'done');
    }
], function (err, result) {
   // result now equals 'done'    
});

https://github.com/caolan/async

% npm install async --save

MONGODB

Benefits

  • Well suited for Agile development
  • Built to scale easily (auto-sharding)

Mongoosejs

var mongoose = require('mongoose');

var todoSchema = {
    item  : String,
    date  : Date
};

exports.model = function(mongoConnection){
    return mongoConnection.model('Todo', todoSchema, 'todos');
};

library for creating data model/validation

exports: Node uses commonjs (http://wiki.commonjs.org/wiki/CommonJS)

model/index.js

CRUD with MONGOOSEJS

var Todo = require('../models/').model(mongoConnection);

this.list = function(req, res){
    Todo.find( { } , function(err, doc){
	res.send(doc);
    });
};

controller/index.js

GET /items

READ

this.read = function(req, res){
    Todo.find( { _id : req.params.idx }, 
        function(err, doc){
	    res.send(doc);
        }
    );
};

GET /items/:idx

{"__v":0,
"date":"2014-11-20T01:39:34.964Z",
"item":"drink sculpin",
"_id":"546d46569142b4887382f1c3"}
{"__v":0,
"date":"2014-11-20T01:39:34.964Z",
"item":"drink sculpin",
"_id":"546d46569142b4887382f1c3"}
{"__v":0,
"date":"2014-11-20T01:39:34.964Z",
"item":"drink sculpin",
"_id":"546d46569142b4887382f1c3"}

CREATE

this.create = function(req, res){
    var newTodo = new Todo();
    newTodo.item = req.body.item;
    newTodo.date = new Date();

    newTodo.save(function(err, doc) {
        if(err)
	    throw err;
    	res.send(doc);
    });
};

Angular

  • Modules
  • Controllers
  • 2-way data binding, $scope
  • $http

Ideally suited for Single Page Applications

MODULES

<body ng-app='app'>
  ...
</body>

html

app.js

angular.module("app",[ ]);

CONTROLLERS

app.controller("todoController", function($scope){ 

    $scope.greeting = "Hello World. This is my todo app";

})
<body ng-app='app'>
  <div ng-controller='todoController'>
    <h1>{{greeting}}</h1>
  </div>
</body>

html template

app.js

SERVICES

 $HTTP

$http.get('http://localhost:3245/item')
  .success(function(result){
    $scope.todos = result;
});

http post

$http.post('http://localhost:3245/item', 
  {item : todo.item})
.success(function(result){
  console.log(result);
});

code demo

PRE-REQS

  • Install MongoDB
  • Install node

SOME PARTING WORDS

YOU DON'T HAVE TO BE MEAN.

Questions?

@edatrero

github.com/eatrero

Intro to the MEAN Stack

By Ed Atrero

Intro to the MEAN Stack

Frontend Authority Meetup for Nov 20, 2014

  • 3,186