Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chapter 05 #26

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
31 changes: 31 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed
.env

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# https://docs.npmjs.com/cli/shrinkwrap#caveats
node_modules

# Debug log from npm
npm-debug.log
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM node:11.2.0-alpine

RUN apk add --no-cache curl-dev libzip-dev autoconf build-base gmp-dev coreutils

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY . /usr/src/app

RUN npm i

EXPOSE 3000

ENV DB_HOST=database

CMD ["npm", "start"]
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: npm start
69 changes: 68 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,68 @@
# gettingMean-2
# gettingMean-2
# Getting MEAN Second Edition application code

This is the code for the sample 'Loc8r' application that is built through the course of the book Getting MEAN Second Edition.

Getting MEAN Second Edition is published by Manning, and teaches readers how to develop web applications end-to-end using the MEAN stack with Node 11 and Angular 7. It is currently in early access through the MEAP program, with new chapters being released regularly.

> Note: if you have the First Edition of the book using Node 4 and Angular 1 you need the [First Edition code](https://github.com/simonholmes/getting-MEAN/) instead.

## The application at various stages

There will be named branches for the various states of the code throughout the book:

* `master` **Chapter 3 start**: A blank Express 4.16.3 project
* `chapter-03` **Chapter 3 end**: Creating and setting up a MEAN project
* `chapter-04-views` **Chapter 4 mid-point**: The data is hard coded into views
* `chapter-04` **Chapter 4 end**: Building a static site with Node.js and Express
* `chapter-05` **Chapter 5**: Building a data model with MongoDB and Mongoose
* `chapter-06` **Chapter 6**: Writing a REST API: Exposing your MongoDB database to the application
* `chapter-07` **Chapter 7**: Consuming a REST API: Using an API from inside Express
* `chapter-08` **Chapter 8**: Creating an Angular application with TypeScript
* `chapter-09` **Chapter 9**: Building a Single Page Application with Angular
* `chapter-10` **Chapter 10**: Building a Single Page Application with Angular: The next level
* `chapter-11` **Chapter 11**: Authenticating users, managing sessions and securing APIs
* `chapter-12` **Chapter 12**: Using an authentication API in Angular applications

## Get the code to run on your machine

Pre-requisites:

* Git installed
* A command line interface capable of running Git commands
* Node v11 installed

To get the code for a specific branch:

`$ git clone -b branch-name https://github.com/cliveharber/gettingMean-2.git`

Then change into the folder the git clone command will create:

`$ cd getting-MEAN-2`

And finally install the dependencies:

`npm install`

## Getting the code via Docker

Pre-requisites:

* Docker

To get the code for a specific branch:

`$ git clone -b branch-name https://github.com/cliveharber/gettingMean-2.git`

Then change into the folder the git clone command will create:

`$ cd getting-MEAN-2`

And finally run the docker containers

`make build`

To remove the containers when complete

`make destroy`

43 changes: 43 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const favicon = require('serve-favicon');
require('./app_server/models/db');

const indexRouter = require('./app_server/routes/index');
const usersRouter = require('./app_server/routes/users');

const app = express();

// view engine setup
app.set('views', path.join(__dirname, 'app_server', 'views'));
app.set('view engine', 'pug');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});

// error handler
app.use(function(err, req, res) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};

// render the error page
res.status(err.status || 500);
res.render('error');
});

module.exports = app;
104 changes: 104 additions & 0 deletions app_server/controllers/locations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
const homelist = (req, res) => {
res.render('locations-list',
{
title: 'Loc8r - find a place to work with wifi',
pageHeader: {
title: 'Loc8r',
strapLine: 'Find places to work with wifi near you!'
},
sidebar: "Looking for wifi and a seat? Loc8r helps you find places to work when out and about. Perhaps with coffee, cake or a pint? Let Loc8r help you find the place you're looking for.",
locations: [
{
name: 'Starcups',
address: '125 High Street, Reading, RG6 1PS',
rating: 3,
facilities: ['Hot drinks', 'Food', 'Premium wifi'],
distance: '100m'
},
{
name: 'Cafe Hero',
address: '125 High Street, Reading, RG6 1PS',
rating: 4,
facilities: ['Hot drinks', 'Food', 'Premium wifi'],
distance: '200m'
},
{
name: 'Burger Queen',
address: '125 High Street, Reading, RG6 1PS',
rating: 2,
facilities: ['Food', 'Premium wifi'],
distance: '250m'
}
]
}
);
};

const locationInfo = (req, res) => {
res.render('location-info',
{
title: 'Starcups',
pageHeader: {
title: 'Loc8r',
},
sidebar: {
context: 'is on Loc8r because it has accessible wifi and space to sit down with your laptop and get some work done.',
callToAction: 'If you\'ve been and you like it - or if you don\'t - please leave a review to help other people just like you.'
},
location: {
name: 'Starcups',
address: '125 High Street, Reading, RG6 1PS',
rating: 3,
facilities: ['Hot drinks', 'Food', 'Premium wifi'],
coords: {lat: 51.455041, lng: -0.9690884},
openingTimes: [
{
days: 'Monday - Friday',
opening: '7:00am',
closing: '7:00pm',
closed: false
},
{
days: 'Saturday',
opening: '8:00am',
closing: '5:00pm',
closed: false
},
{
days: 'Sunday',
closed: true
}
],
reviews: [
{
author: 'Simon Holmes',
rating: 5,
timestamp: '16 July 2013',
reviewText: 'What a great place. I can\'t say enough good things about it.'
},
{
author: 'Charlie Chaplin',
rating: 3,
timestamp: '16 June 2013',
reviewText: 'It was okay. Coffee wasn\'t great, but the wifi was fast.'
}
]
}
}
);
};

const addReview = (req, res) => {
res.render('location-review-form',
{
title: 'Review Starcups on Loc8r' ,
pageHeader: { title: 'Review Starcups' }
}
);
};

module.exports = {
homelist,
locationInfo,
addReview
};
13 changes: 13 additions & 0 deletions app_server/controllers/others.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* GET homepage */
const about = (req, res) => {
res.render('generic-text',
{
title: 'About Loc8r',
content: 'Loc8r was created to help people find places to sit down and get a bit of work done.\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc sed lorem ac nisi dignissim accumsan. Nullam sit amet interdum magna. Morbi quis faucibus nisi. Vestibulum mollis purus quis eros adipiscing tristique. Proin posuere semper tellus, id placerat augue dapibus ornare. Aenean leo metus, tempus in nisl eget, accumsan interdum dui. Pellentesque sollicitudin volutpat ullamcorper.'
}
);
};

module.exports = {
about
};
61 changes: 61 additions & 0 deletions app_server/models/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const mongoose = require('mongoose');
const readLine = require('readline');

let dbURL = 'mongodb://127.0.0.1/Loc8r';
if (process.env.NODE_ENV === 'production') {
dbURL = process.env.DB_HOST || process.env.MONGODB_URI;
}

const connect = () => {
setTimeout(() => mongoose.connect(dbURL, { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true }), 1000);
}

mongoose.connection.on('connected', () => {
console.log('connected');
});

mongoose.connection.on('error', err => {
console.log('error: ' + err);
return connect();
});

mongoose.connection.on('disconnected', () => {
console.log('disconnected');
});

if (process.platform === 'win32') {
const rl = readLine.createInterface({
input: process.stdin,
output: process.stdout
});
rl.on ('SIGINT', () => {
process.emit("SIGINT");
});
}

const gracefulShutdown = (msg, callback) => {
mongoose.connection.close( () => {
console.log(`Mongoose disconnected through ${msg}`);
callback();
});
};

process.once('SIGUSR2', () => {
gracefulShutdown('nodemon restart', () => {
process.kill(process.pid, 'SIGUSR2');
});
});
process.on('SIGINT', () => {
gracefulShutdown('app termination', () => {
process.exit(0);
});
});
process.on('SIGTERM', () => {
gracefulShutdown('Heroku app shutdown', () => {
process.exit(0);
});
});

connect();

require('./locations');
Loading