diff --git a/chapter11/app.js b/chapter11/app.js
new file mode 100644
index 0000000..cbba0ec
--- /dev/null
+++ b/chapter11/app.js
@@ -0,0 +1,32 @@
+var express = require('express');
+var app = express();
+
+// Route One
+app.get('/teams/:teamName/employees/:employeeId', function (req, res, next) {
+ console.log('teamName = ' + req.params.teamName);
+ console.log('employeeId = ' + req.params.employeeId);
+ res.send('path one');
+});
+
+// Route Two
+app.get('/teams/:teamName/employees', function (req, res, next) {
+ console.log('setting content type');
+ res.set('Content-Type', 'application/json');
+ res.locals.data = 100 ;
+ next();
+}, function (req, res, next) {
+ console.log('teamName = ' + req.params.teamName);
+ console.log(res.locals.data);
+ res.send('path two');
+});
+
+// Route Three
+app.get(/^\/groups\/(\w+)\/(\d+)$/, function (req, res, next) {
+ console.log('groupname = ' + req.params[0]);
+ console.log('groupId = ' + req.params[1]);
+ res.send('path three');
+});
+
+var server = app.listen(1337, function() {
+ console.log('Server started on port 1337');
+});
diff --git a/chapter12/users.js b/chapter12/users.js
new file mode 100644
index 0000000..74b4f33
--- /dev/null
+++ b/chapter12/users.js
@@ -0,0 +1,38 @@
+var express = require('express');
+var router = express.Router();
+
+/* GET users listing. */
+router.get('/', function(req, res, next) {
+ setTimeout(function() {
+ res.locals.users = [{
+ first: 'Abraham',
+ last: 'Lincoln'
+ }, {
+ first: 'Andrew',
+ last: 'Johnson'
+ }, {
+ first: 'Ulysses',
+ last: 'Grant'
+ }];
+ return next();
+ }, 1000)
+}, function (req, res, next) {
+ res.locals.time = Date.now();
+ res.set({
+ 'X-Special-Header': 'MEAN Stack'
+ });
+
+ var view = ''
+ + '
User Output
';
+ for (var i = 0, length = res.locals.users.length; i < length; i++) {
+ var user = res.locals.users[i];
+ view += '' + user.first + ' | ' + user.last + ' |
';
+ }
+
+ view += '
';
+
+ res.send(view);
+});
+
+module.exports = router;
diff --git a/chapter14/index.js b/chapter14/index.js
new file mode 100644
index 0000000..39b3f91
--- /dev/null
+++ b/chapter14/index.js
@@ -0,0 +1,73 @@
+var Hapi = require('hapi');
+var server = new Hapi.Server('localhost', 3000);
+
+server.route({
+ method: 'GET',
+ path: '/users',
+ config: {
+ handler: function (request, reply) {
+ var result = {};
+ setTimeout(function () {
+ result.users = [{
+ first: 'Abraham',
+ last: 'Lincoln'
+ }, {
+ first: 'Andrew',
+ last: 'Johnson'
+ }, {
+ first: 'Ulysses',
+ last: 'Grant'
+ }];
+ result.time = Date.now();
+
+ return reply(result).header('X-Special-Header', 'MEAN Stack');
+ }, 3000);
+ }
+ }
+});
+
+var plug = {
+ register: function (plugin, options, next) {
+ plugin.route({
+ method: 'GET',
+ path: options.prefix + '/view',
+ config: {
+ handler: function (request, reply) {
+ request.server.inject({
+ url: '/users'
+ }, function (res) {
+ var users = res.result.users;
+ var view = 'User Output
';
+
+ for (var i = 0; i < users.length; i++) {
+ var user = users[i];
+ view += '' + user.first + ' | ' + user.last + ' |
';
+ }
+
+ view += '
';
+ reply(view);
+ });
+ }
+ }
+ });
+
+ next();
+ }
+};
+plug.register.attributes = {
+ name: 'viewer',
+ version: '1.0.0'
+};
+
+server.pack.register({
+ plugin: plug,
+ options: {
+ prefix: '/users'
+ }
+}, function (err) {
+ if (err) {
+ console.log(err);
+ } else {
+ server.start();
+ }
+});
diff --git a/chapter16/listing16-1.html b/chapter16/listing16-1.html
new file mode 100644
index 0000000..d7a5234
--- /dev/null
+++ b/chapter16/listing16-1.html
@@ -0,0 +1,13 @@
+
+
+
+
+ Gender {{gender}}
+ Male
+ Female
+
+ Welcome {{firstName + ' ' + lastName}}
+
+
+
+
diff --git a/chapter16/listing16-2.js b/chapter16/listing16-2.js
new file mode 100644
index 0000000..05ccf61
--- /dev/null
+++ b/chapter16/listing16-2.js
@@ -0,0 +1,15 @@
+var app = angular.module('app', []);
+app.controller('main', ['$scope', function($scope) {
+ $scope.firstName = $scope.lastName = undefined;
+ $scope.gender = 'female';
+ $scope.style = {color:'orange'};
+
+ $scope.signup = function () {
+ var person = {
+ first: $scope.firstName,
+ last: $scope.lastName,
+ gender: $scope.gender
+ }
+ console.log(person);
+ };
+}]);
diff --git a/chapter16/listing16-3.html b/chapter16/listing16-3.html
new file mode 100644
index 0000000..7384623
--- /dev/null
+++ b/chapter16/listing16-3.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+ {{p.first}} |
+ {{p.last}} |
+ |
+
+
+
+
+
+
diff --git a/chapter18/listing18-2.html b/chapter18/listing18-2.html
new file mode 100644
index 0000000..fffbbcc
--- /dev/null
+++ b/chapter18/listing18-2.html
@@ -0,0 +1,60 @@
+
+
+
+
+
+ {{$index}} - {{e}}
+
+
+
+
+
+
diff --git a/chapter18/listing18-3.html b/chapter18/listing18-3.html
new file mode 100644
index 0000000..81916d1
--- /dev/null
+++ b/chapter18/listing18-3.html
@@ -0,0 +1,73 @@
+
+
+
+
+
+ {{$index}} - {{e}}
+
+
+
+
+
+
diff --git a/chapter19/edit.html b/chapter19/edit.html
new file mode 100644
index 0000000..011d3cb
--- /dev/null
+++ b/chapter19/edit.html
@@ -0,0 +1,6 @@
+
+Back <<<
diff --git a/chapter19/index.html b/chapter19/index.html
new file mode 100644
index 0000000..bb67c3e
--- /dev/null
+++ b/chapter19/index.html
@@ -0,0 +1,10 @@
+
+
+ Your Human Resource Application
+
+
+
+
+
+
+
diff --git a/chapter19/view.html b/chapter19/view.html
new file mode 100644
index 0000000..86abbb3
--- /dev/null
+++ b/chapter19/view.html
@@ -0,0 +1,8 @@
+
+
+ {{p.id}} |
+ {{p.first}} |
+ {{p.last}} |
+ Edit >>> |
+
+
diff --git a/chapter19/webapp.js b/chapter19/webapp.js
new file mode 100644
index 0000000..663d233
--- /dev/null
+++ b/chapter19/webapp.js
@@ -0,0 +1,47 @@
+var app = angular.module('app', ['ngRoute', 'ngResource']);
+
+app.config(['$routeProvider', function ($routeProvider) {
+
+ $routeProvider
+ .when('/view', {
+ templateUrl: 'view.html',
+ controller: 'view'
+ })
+ .when('/edit/:employeeId', {
+ templateUrl: 'edit.html',
+ controller: 'edit'
+ })
+ .otherwise({
+ redirectTo: '/'
+ });
+}]);
+
+app.factory('EmployeeService', ['$resource', function ($resource) {
+ return $resource('/employees/:employeeId', {}, {
+ list: {
+ isArray: true
+ },
+ get: {
+ isArray: false
+ }
+ });
+}]);
+
+app.controller('view', ['$scope', 'EmployeeService', function ($scope, EmployeeService) {
+ $scope.employees = [];
+ $scope.firstName = $scope.lastName = '';
+
+ EmployeeService.list(function (data) {
+ $scope.employees = data;
+ });
+}]);
+
+app.controller('edit', ['$scope', 'EmployeeService','$routeParams', function ($scope, EmployeeService, $routeParams) {
+ $scope.employee = {};
+
+ EmployeeService.get({
+ employeeId: $routeParams.employeeId
+ }, function (data) {
+ $scope.employee = data;
+ });
+}]);
diff --git a/chapter2/chapter2.js b/chapter2/chapter2.js
new file mode 100644
index 0000000..a9170ea
--- /dev/null
+++ b/chapter2/chapter2.js
@@ -0,0 +1,33 @@
+var http = require('http');
+var fs = require('fs');
+
+http.createServer(function (req, res) {
+ if (req.url === '/favicon.ico') {
+ return res.end();
+ }
+ console.log('Incoming request to ' + req.url);
+
+ var i = 2;
+ res.writeHead(200, {'Content-Type': 'text/plain'});
+
+ setTimeout(function() {
+ fs.readFile(__filename, {
+ encoding: 'utf8'
+ }, function (error, contents) {
+
+ if (error) {
+ console.error(error);
+ return res.end();
+ }
+
+ console.log('sending response for ' + req.url);
+ res.end(contents);
+ });
+ }, 5000);
+
+ while(i--) {
+ console.log('Loop value: ' + i + '\r');
+ }
+}).listen(1337, '127.0.0.1');
+
+console.log('Server running at http://127.0.0.1:1337/');
diff --git a/chapter21/edit_controller.js b/chapter21/edit_controller.js
new file mode 100644
index 0000000..471a368
--- /dev/null
+++ b/chapter21/edit_controller.js
@@ -0,0 +1,3 @@
+app.controller('edit', ['$scope', 'EmployeeService','$routeParams', function($scope, EmployeeService, $routeParams) {
+ // See Listing 19-3 for complete code
+}]);
diff --git a/chapter21/gulp.js b/chapter21/gulp.js
new file mode 100644
index 0000000..431ef19
--- /dev/null
+++ b/chapter21/gulp.js
@@ -0,0 +1,48 @@
+var gulp = require('gulp');
+var stylus = require('gulp-stylus');
+var concat = require('gulp-concat');
+var rename = require('gulp-rename');
+var uglify = require('gulp-uglify');
+var wrap = require('gulp-wrap');
+var jshint = require('gulp-jshint');
+
+var jsSource = './assets/javascript/';
+
+gulp.task('css', function() {
+ gulp.src('./assets/style/*.styl')
+ .pipe(stylus({
+ compress: true
+ }))
+ .pipe(concat('main.css', {
+ newLine: ''
+ }))
+ .pipe(gulp.dest('./public/css'));
+});
+
+gulp.task('javascript', function() {
+ gulp.src([jsSource + 'mainapp.js',
+ jsSource + 'edit_controller.js',
+ jsSource + 'view_controller.js'])
+ .pipe(concat('main.js'))
+ .pipe(wrap('(function(a, window){<%= contents %>}(angular, window));'))
+ .pipe(jshint({
+ predef: ['window', 'angular']
+ }))
+ .pipe(jshint.reporter('default'))
+ .pipe(gulp.dest('./public/javascript'))
+ .pipe(rename({
+ suffix: '.min'
+ }))
+ .pipe(uglify())
+ .pipe(gulp.dest('./public/javascript'))
+});
+
+gulp.task('watch', function() {
+ gulp.watch('./assets/javascript/*.js', ['javascript']);
+ gulp.watch('./assets/style/*.styl', ['css']);
+});
+
+gulp.task('default', function() {
+ gulp.start('css');
+ gulp.start('javascript');
+});
diff --git a/chapter21/mainapp.js b/chapter21/mainapp.js
new file mode 100644
index 0000000..72d2037
--- /dev/null
+++ b/chapter21/mainapp.js
@@ -0,0 +1,9 @@
+var app = angular.module('app', ['ngRoute', 'ngResource']);
+
+app.config(['$routeProvider', function($routeProvider) {
+ // See Listing 19-2 for complete code
+}]);
+
+app.factory('EmployeeService', ['$resource', function($resource) {
+ // See Listing 19-3 for complete code
+}]);
diff --git a/chapter21/view_controller.js b/chapter21/view_controller.js
new file mode 100644
index 0000000..630145f
--- /dev/null
+++ b/chapter21/view_controller.js
@@ -0,0 +1,3 @@
+app.controller('view', ['$scope', 'EmployeeService', function($scope, EmployeeService) {
+ // See Listing 19-3 for complete code
+}]);
diff --git a/chapter3/mmm.js b/chapter3/mmm.js
new file mode 100644
index 0000000..ae8c1a0
--- /dev/null
+++ b/chapter3/mmm.js
@@ -0,0 +1,26 @@
+exports.add = add;
+exports.multiply = multiply;
+exports.factorial = factorial;
+
+exports.now = Date.now();
+
+function add (number1, number2) {
+ return parseInt(number1, 10) + parseInt(number2, 10);
+}
+
+function multiply (number1, number2) {
+ return parseInt(number1, 10) * parseInt(number2, 10);
+}
+
+function factorial (number) {
+ if (number === 0) {
+ return 1;
+ }
+ else {
+ return number * factorial(number - 1);
+ }
+}
+
+function privateMethod () {
+ console.log('not accessable from outside this file')
+}
diff --git a/chapter3/package.json b/chapter3/package.json
new file mode 100644
index 0000000..6f5be92
--- /dev/null
+++ b/chapter3/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "hr",
+ "version": "1.0.0",
+ "scripts": {
+ "start": "echo \"Run the correct js file to start your application\" && exit 0",
+ "populate": "node ./bin/populate_db"
+ },
+ "dependencies": {
+ "async": "0.9.0",
+ "debug": "0.7.4",
+ "express": "4.2.0",
+ "mongoose": "3.8.11"
+ }
+}
diff --git a/chapter3/test.js b/chapter3/test.js
new file mode 100644
index 0000000..8ef9590
--- /dev/null
+++ b/chapter3/test.js
@@ -0,0 +1,12 @@
+var m = require('./mmm');
+
+console.log('time after first require ' + m.now);
+
+console.log(m.add(3,5));
+console.log(m.multiply(4,5));
+console.log(m.factorial(4));
+
+setTimeout(function () {
+ m = require('./mmm');
+ console.log('time after second require ' + m.now);
+}, 5000);
diff --git a/chapter6/employees.js b/chapter6/employees.js
new file mode 100644
index 0000000..36c47c1
--- /dev/null
+++ b/chapter6/employees.js
@@ -0,0 +1,24 @@
+var employeeDb = require('./employees.json');
+
+exports.getEmployees = getEmployees;
+exports.getEmployee = getEmployee;
+
+function getEmployees (callback) {
+ setTimeout(function () {
+ callback(null, employeeDb);
+ }, 1000);
+}
+
+function getEmployee (employeeId, callback) {
+ getEmployees(function (error, data) {
+ if (error) {
+ return callback(error);
+ }
+
+ var result = data.find(function(item) {
+ return item.id === employeeId;
+ });
+
+ callback(null, result);
+ });
+}
diff --git a/chapter6/employees.json b/chapter6/employees.json
new file mode 100644
index 0000000..6af2bf3
--- /dev/null
+++ b/chapter6/employees.json
@@ -0,0 +1,28 @@
+[
+ {
+ "id": "1000003",
+ "name": {
+ "first": "Colin",
+ "last": "Ihrig"
+ },
+ "address": {
+ "lines": ["11 Wall Street"],
+ "city": "New York",
+ "state": "NY",
+ "zip": 10118
+ }
+ },
+ {
+ "id": "1000021",
+ "name": {
+ "first": "Adam",
+ "last": "Bretz"
+ },
+ "address": {
+ "lines": ["2 Market Square","(Market Square)"],
+ "city": "Pittsburgh",
+ "state": "PA",
+ "zip": 15222
+ }
+ }
+]
diff --git a/chapter6/index.js b/chapter6/index.js
new file mode 100644
index 0000000..261bf5c
--- /dev/null
+++ b/chapter6/index.js
@@ -0,0 +1,58 @@
+var http = require('http');
+var employeeService = require('./employees');
+var responder = require('./responseGenerator');
+var staticFile = responder.staticFile('/public');
+
+Array.prototype.find = function (predicate) {
+ for (var i = 0, value; i < this.length; i++) {
+ value = this[i];
+ if (predicate.call(this, value))
+ return value;
+ }
+ return undefined;
+}
+
+
+http.createServer(function (req, res) {
+ // A parsed url to work with in case there are parameters
+ var _url;
+
+ // In case the client uses lower case for methods.
+ req.method = req.method.toUpperCase();
+ console.log(req.method + ' ' + req.url);
+
+ if (req.method !== 'GET') {
+ res.writeHead(501, {
+ 'Content-Type': 'text/plain'
+ });
+ return res.end(req.method + ' is not implemented by this server.');
+ }
+
+ if (_url = /^\/employees$/i.exec(req.url)) {
+ employeeService.getEmployees(function (error, data) {
+ if (error) {
+ return responder.send500(error, res);
+ }
+ return responder.sendJson(data, res);
+ });
+ } else if (_url = /^\/employees\/(\d+)$/i.exec(req.url)) {
+ employeeService.getEmployee(_url[1], function (error, data) {
+ if (error) {
+ return responder.send500(error, res);
+ }
+
+ if (!data) {
+ return responder.send404(res);
+ }
+
+ return responder.sendJson(data,res);
+ });
+ }
+ else {
+ // try to send the static file
+ res.writeHead(200);
+ res.end('static file maybe');
+ }
+}).listen(1337, '127.0.0.1');
+
+console.log('Server running at http://127.0.0.1:1337/');
diff --git a/chapter6/responseGenerator.js b/chapter6/responseGenerator.js
new file mode 100644
index 0000000..424d66a
--- /dev/null
+++ b/chapter6/responseGenerator.js
@@ -0,0 +1,47 @@
+var fs = require('fs');
+
+exports.send404 = function (response) {
+ console.error("Resource not found".yellow);
+
+ response.writeHead(404, {
+ 'Content-Type': 'text/plain'
+ });
+ response.end('Not Found');
+}
+
+exports.sendJson = function (data, response) {
+ response.writeHead(200, {
+ 'Content-Type': 'application/json'
+ });
+
+ response.end(JSON.stringify(data));
+}
+
+exports.send500 = function (data, response) {
+ console.error(data.red);
+
+ response.writeHead(500, {
+ 'Content-Type': 'text/plain'
+ });
+ response.end(data);
+}
+
+exports.staticFile = function (staticPath) {
+ return function(data, response) {
+ var readStream;
+
+ // Fix so routes to /home and /home.html both work.
+ data = data.replace(/^(\/home)(.html)?$/i,'$1.html');
+ data = '.' + staticPath + data;
+
+ fs.stat(data, function (error, stats) {
+
+ if (error || stats.isDirectory()) {
+ return exports.send404(response);
+ }
+
+ readStream = fs.createReadStream(data);
+ return readStream.pipe(response);
+ });
+ }
+}
diff --git a/chapter8/index.js b/chapter8/index.js
new file mode 100644
index 0000000..f573648
--- /dev/null
+++ b/chapter8/index.js
@@ -0,0 +1,198 @@
+var mongoose = require('mongoose');
+var Schema = mongoose.Schema;
+var db = mongoose.connection;
+var dbUrl = 'mongodb://username:password@ds043917.mongolab.com:43917/humanresources';
+
+var TeamSchema = new Schema({
+ name: {
+ type: String,
+ required: true
+ }
+});
+var Team = mongoose.model('Team', TeamSchema);
+
+var EmployeeSchema = new Schema({
+ name: {
+ first: {
+ type: String,
+ required: true
+ },
+ last: {
+ type: String,
+ required: true
+ }
+ },
+ team: {
+ type: Schema.Types.ObjectId,
+ ref: 'Team'
+ },
+ image: {
+ type: String,
+ default: 'images/user.png'
+ },
+ address: {
+ lines: {
+ type: [String]
+ },
+ postal: {
+ type: String
+ }
+ }
+});
+
+var Employee = mongoose.model('Employee', EmployeeSchema);
+
+
+db.on('error', function () {
+ console.log('there was an error communicating with the database');
+});
+
+function insertTeams (callback) {
+ Team.create([{
+ name: 'Product Development'
+ }, {
+ name: 'Dev Ops'
+ }, {
+ name: 'Accounting'
+ }], function (error, pd, devops, acct) {
+ if (error) {
+ return callback(error);
+ } else {
+ console.info('teams successfully added')
+ callback(null, pd, devops, acct);
+ }
+ });
+}
+
+function insertEmployees (pd, devops, acct, callback) {
+ Employee.create([{
+ name: {
+ first: 'John',
+ last: 'Adams'
+ },
+ team: pd._id,
+ address: {
+ lines: ['2 Lincoln Memorial Cir NW'],
+ postal: '20037'
+ }
+ }, {
+ name: {
+ first: 'Thomas',
+ last: 'Jefferson'
+ },
+ team: devops._id,
+ address: {
+ lines: ['1600 Pennsylvania Avenue', 'White House'],
+ postal: '20500'
+ }
+ }, {
+ name: {
+ first: 'James',
+ last: 'Madison'
+ },
+ team: acct._id,
+ address: {
+ lines: ['2 15th St NW', 'PO Box 8675309'],
+ postal: '20007'
+ }
+ }, {
+ name: {
+ first: 'James',
+ last: 'Monroe'
+ },
+ team: acct._id,
+ address: {
+ lines: ['1850 West Basin Dr SW', 'Suite 210'],
+ postal: '20242'
+ }
+ }], function (error, johnadams) {
+ if (error) {
+ return callback(error);
+ } else {
+ console.info('employees successfully added');
+ callback(null, {
+ team: pd,
+ employee: johnadams
+ });
+ }
+ })
+}
+
+function retrieveEmployee (data, callback) {
+ Employee.findOne({
+ _id: data.employee._id
+ }).populate('team').exec(function (error, result) {
+ if (error) {
+ return callback (error);
+ } else {
+ console.log('*** Single Employee Result ***');
+ console.dir(result);
+ callback(null, data);
+ }
+ });
+}
+
+function retrieveEmployees (data, callback) {
+ Employee.find({
+ 'name.first': /J/i
+ }, function (error, results) {
+ if (error) {
+ return callback(error);
+ } else {
+ console.log('*** Multiple Employees Result ***')
+ console.dir(results);
+ callback(null, data);
+ }
+ });
+}
+
+function updateEmployee (first, last, data, callback) {
+ console.log('*** Changing names ***');
+ console.dir(data.employee);
+
+ var employee = data.employee;
+ employee.name.first = first;
+ employee.name.last = last
+
+ employee.save(function (error, result) {
+ if (error) {
+ return callback(error);
+ } else {
+ console.log('*** Changed name to Andrew Jackson ***');
+ console.log(result);
+ callback(null, data);
+ }
+ });
+}
+
+mongoose.connect(dbUrl, function (err) {
+ if (err) {
+ return console.log('there was a problem connecting to the database!' + err);
+ }
+ console.log('connected!');
+
+ insertTeams(function (err, pd, devops, acct) {
+ if (err) {
+ return console.log(err)
+ }
+ insertEmployees(pd, devops, acct, function (err, result) {
+
+ retrieveEmployee(result, function (err, result) {
+
+ retrieveEmployees(result, function (err, result) {
+
+ updateEmployee('Andrew', 'Jackson', result, function (err, result) {
+ if (err) {
+ console.error(err);
+ } else {
+ console.info('database activity complete')
+ }
+
+ db.close();
+ process.exit();
+ });
+ });
+ });
+ });
+ });
+});