From 126f038ac5fde4c8418e6f6731c7716df57877d5 Mon Sep 17 00:00:00 2001 From: Simon Mackie Date: Wed, 10 Dec 2014 10:41:46 +0000 Subject: [PATCH] Initial commit --- chapter11/app.js | 32 ++++++ chapter12/users.js | 38 +++++++ chapter14/index.js | 73 +++++++++++++ chapter16/listing16-1.html | 13 +++ chapter16/listing16-2.js | 15 +++ chapter16/listing16-3.html | 43 ++++++++ chapter18/listing18-2.html | 60 +++++++++++ chapter18/listing18-3.html | 73 +++++++++++++ chapter19/edit.html | 6 ++ chapter19/index.html | 10 ++ chapter19/view.html | 8 ++ chapter19/webapp.js | 47 ++++++++ chapter2/chapter2.js | 33 ++++++ chapter21/edit_controller.js | 3 + chapter21/gulp.js | 48 +++++++++ chapter21/mainapp.js | 9 ++ chapter21/view_controller.js | 3 + chapter3/mmm.js | 26 +++++ chapter3/package.json | 14 +++ chapter3/test.js | 12 +++ chapter6/employees.js | 24 +++++ chapter6/employees.json | 28 +++++ chapter6/index.js | 58 ++++++++++ chapter6/responseGenerator.js | 47 ++++++++ chapter8/index.js | 198 ++++++++++++++++++++++++++++++++++ 25 files changed, 921 insertions(+) create mode 100644 chapter11/app.js create mode 100644 chapter12/users.js create mode 100644 chapter14/index.js create mode 100644 chapter16/listing16-1.html create mode 100644 chapter16/listing16-2.js create mode 100644 chapter16/listing16-3.html create mode 100644 chapter18/listing18-2.html create mode 100644 chapter18/listing18-3.html create mode 100644 chapter19/edit.html create mode 100644 chapter19/index.html create mode 100644 chapter19/view.html create mode 100644 chapter19/webapp.js create mode 100644 chapter2/chapter2.js create mode 100644 chapter21/edit_controller.js create mode 100644 chapter21/gulp.js create mode 100644 chapter21/mainapp.js create mode 100644 chapter21/view_controller.js create mode 100644 chapter3/mmm.js create mode 100644 chapter3/package.json create mode 100644 chapter3/test.js create mode 100644 chapter6/employees.js create mode 100644 chapter6/employees.json create mode 100644 chapter6/index.js create mode 100644 chapter6/responseGenerator.js create mode 100644 chapter8/index.js 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 += ''; + } + + view += '
' + user.first + '' + user.last + '
'; + + 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 += ''; + } + + view += '
' + user.first + '' + user.last + '
'; + 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 @@ + + +
+ + + + + + + + + +
{{p.id}}{{p.first}} {{p.last}}
+
+
+
+        

{{$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 @@ + + +
+ + + + + + + + + +
{{p.id}}{{p.first}} {{p.last}}
+
+
+
+        

{{$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 @@ +
+ {{employee.first}} {{employee.last}} + + +
+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(); + }); + }); + }); + }); + }); +});