%Teilweise Erzeugt mit dem LaTeX-Generator: http://latex.sehnot.de

%Schriftgröße, Layout, Papierformat, Art des Dokumentes
\documentclass[10pt,oneside,a4paper]{scrartcl}

%Einstellungen der Seitenränder
\usepackage[left=2cm,right=2cm,top=1.5cm,bottom=1.5cm,includeheadfoot]{geometry}

%neue Rechtschreibung
\usepackage[ngerman]{babel}

%Umlaute ermöglichen
\usepackage[utf8]{inputenc}

%Gesamtseitenzahl
\usepackage{lastpage}

% Kopf- und Fußzeile
\usepackage[automark]{scrpage2}

%Quellcode-Listings
\usepackage{listings}

%Hyperlinks
\usepackage{hyperref}

% Rahmen um Verbatim
\usepackage{fancyvrb}
\usepackage{moreverb}



%Kopfzeile
\ihead{Webentwicklung}
\chead{}
\ohead{http://kohnlehome.de/html/node-express.pdf}
\setheadsepline{0.5pt}

%Fußzeile
\setfootsepline{0.5pt}
\ifoot{Franz Kohnle}
\cfoot{Seite \thepage\ von  \pageref{LastPage}}
\ofoot{\today}

\pagestyle{scrheadings}

\begin{document}

% Überschrift 
\begin{center}
\LARGE % Schriftgröße
\bfseries % Fettdruck
\sffamily % Serifenlose Schrift
WebApp mit Node und Express
\end{center}



\section{Installation von Node.js}
\subsection*{Download}
\href{https://nodejs.org/}{nodejs.org}

\subsection*{Test}
\begin{tabular}{l l}
\texttt{\$ node -v} & v8.9.1\\
\texttt{\$ npm -v} &  5.5.1
\end{tabular}

\section{Projekt erstellen}
\begin{tabular}{l l}
\texttt{\$ npm init} & erstellt im aktuellen Verzeichnis die Datei \textit{package.json}
\end{tabular}

\section{Hallo Welt in Konsole}
\subsection*{index.js}
\begin{boxedverbatim}
console.log('Hallo Welt!');
\end{boxedverbatim}

\subsection*{Script starten}
\begin{tabular}{l l}
\texttt{\$ node index.js} & 
\end{tabular}

\section{Webserver nur mit Node}
\subsection*{index.js}
\begin{boxedverbatim}
const http = require("http");

http.createServer(function(request, response) {
   response.writeHead(200, {'Content-Type': 'text/plain'});
   response.end('Hallo Welt!');
}).listen(3000);

console.log('Server läuft auf Port 3000');
\end{boxedverbatim}

\subsection*{Script starten}
\begin{tabular}{l l}
\texttt{\$ node index.js} & 
\end{tabular}

\subsection*{Mit Browser auf Webserver zugreifen}
\begin{tabular}{l l}
\texttt{http:\textbackslash\textbackslash localhost:3000 } & 
\end{tabular}

\newpage

\section{Webanwendung mit express}
\subsection*{express installieren}
\begin{tabular}{l l}
\texttt{\$ npm install express --save} & Installation im aktuellen Verzeichnis, Dependency in package.json
\end{tabular}

\subsection*{index.js}
\begin{boxedverbatim}
const express = require('express');
const app = express();

app.get('/', function(req, res) {
  res.send('Hallo Welt!');
});

app.listen(3000, function() {
  console.log('Server läuft auf Port 3000');
});
\end{boxedverbatim}

\subsection*{Webserver starten}
\begin{tabular}{l l}
\texttt{\$ node index.js} & 
\end{tabular}

\subsection*{Mit Browser auf Webserver zugreifen}
\begin{tabular}{l l}
\texttt{http:\textbackslash\textbackslash localhost:3000 } & 
\end{tabular}

\section{Webanwendung mit express und index.html}
\subsection*{index.html}
\begin{boxedverbatim}
<!doctype html>
<html>
...
\end{boxedverbatim}

\subsection*{index.js}
\begin{boxedverbatim}
...
  res.sendFile(__dirname + '/index.html');
...
\end{boxedverbatim}

\subsection*{Webserver neu starten}
\begin{tabular}{l l}
STRG + C & \\
\texttt{\$ node index.js} & 
\end{tabular}

\newpage

\section{Webanwendung mit express und ejs}
\subsection*{ejs installieren}
\begin{tabular}{l l}
\texttt{\$ npm install ejs --save} & Installation im aktuellen Verzeichnis, Dependency in package.json
\end{tabular}

\subsection*{Template: views/index.ejs}
\begin{boxedverbatim}
<html>
....
<p>Guten Tag, <%= person.vorname %> <%= person.nachname %>!</p>
\end{boxedverbatim}

\subsection*{index.js}
\begin{boxedverbatim}
const express = require('express');
const app = express();

var mensch = { vorname: 'Franz', nachname: 'Kohnle' };

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

app.get('/', function(req, res){
    res.render('index', { person: mensch });
});

app.listen(3000, function(){
    console.log('Server läuft auf Port 3000');
});
\end{boxedverbatim}

\subsection*{Webserver starten}
\begin{tabular}{l l}
\texttt{\$ node index.js} & 
\end{tabular}

\subsection*{Mit Browser auf Webserver zugreifen}
\begin{tabular}{l l}
\texttt{http:\textbackslash\textbackslash localhost:3000 } & 
\end{tabular}

\section{Statische Dateien ausliefern}
\subsection*{Verzeichnisstruktur}
\begin{verbatim}
projekt/
   |- index.js
   |- package.json
   |
   |- views/
   |    |- index.ejs
   |
   |- public/
        |- layout.css
\end{verbatim}

\subsection*{index.js}
\begin{boxedverbatim}
...
app.use(express.static(__dirname + '/public'));
...
\end{boxedverbatim}

\subsection*{index.ejs}
\begin{boxedverbatim}
...
<link rel="stylesheet" type="text/css" href="./layout.css" />
...
\end{boxedverbatim}

\subsection*{layout.css}
\begin{boxedverbatim}
...
\end{boxedverbatim}

\section{Datenbank mit MongoDB}
\subsection*{Server starten}
\begin{tabular}{l l}
\texttt{\$ mongod --dbpath projekt/data/} & \\
\end{tabular}

\subsection*{Client starten}
\begin{tabular}{l l}
\texttt{\$ mongo} & \\
\end{tabular}

\subsection*{Datenbank erstellen}
\begin{tabular}{l l}
\texttt{> use todolist} & Datenbank\\
\texttt{> db.createCollection('aufgaben')} & Collection\\
\end{tabular}

\subsection*{Datensätze erstellen}
\begin{tabular}{l l}
\texttt{db.aufgaben.insert({ text: 'Kuchen backen' })} & \\
\texttt{db.aufgaben.insert({ text: 'Brotzeit machen' })} & \\
\texttt{db.aufgaben.insert({ text: 'Blöd schauen' })} & 
\end{tabular}


\section{In Webanwendung auf MongoDB zugreifen}
\subsection*{mongodb installieren}
\begin{tabular}{l l}
\texttt{\$ npm install mongodb --save} & Installation im aktuellen Verzeichnis, Dependency in package.json
\end{tabular}

\subsection*{Template: views/index.ejs}
\begin{boxedverbatim}
<h1>Todoliste</h1>
<ul>
    <% liste.forEach(function(aufgabe) { %>
        <li><%= aufgabe.text %></li>
    <% }); %>
</ul>
\end{boxedverbatim}

\subsection*{index.js}
\begin{boxedverbatim}
const express = require('express');
const app = express();
const MongoClient = require('mongodb').MongoClient;

app.use(express.static(__dirname + '/public'));
app.set('view engine', 'ejs')

app.get('/', function(req, res){
    MongoClient.connect('mongodb://localhost:27017/todolist', function (err, db) {
        if (err) throw err
        db.collection('aufgaben').find().toArray(function (err, result) {
            if (err) throw err
            res.render('index', {liste: result} );
        })
   })
});

app.listen(3000, function(){
    console.log('Server läuft auf Port 3000');
});
\end{boxedverbatim}

\subsection*{Webserver starten}
\begin{tabular}{l l}
\texttt{\$ node index.js} & 
\end{tabular}

\subsection*{Mit Browser auf Webserver zugreifen}
\begin{tabular}{l l}
\texttt{http:\textbackslash\textbackslash localhost:3000 } & 
\end{tabular}

\section{Webserver nur starten, wenn Verbindung zu MongoDB steht}
\subsection*{index.js}
\begin{boxedverbatim}
const express = require('express');
const app = express();

app.use(express.static(__dirname + '/public'));
app.set('view engine', 'ejs');

const MongoClient = require('mongodb').MongoClient;

// Verbindung mit Datenbank aufbauen
var db;

MongoClient.connect('mongodb://localhost:27017/todolist', function (err, database) {
    if (err) throw err;
    db = database;
    // Webserver startet nur, wenn Datenbankverbindung ok
    app.listen(3000, function(){
        console.log('Höre auf Port 3000');
    });
})

app.get('/', function(req, res){
    db.collection('aufgaben').find().toArray(function (err, result) {
        if (err) throw err
        res.render('index', {liste: result} );
    });
});
\end{boxedverbatim}

\section{Neue Datensätze mit Formular übergeben}
\subsection*{body-parser installieren}
\begin{tabular}{l l}
\texttt{\$ npm install body-parser --save} & Zum Lesen des HTTP-Bodys
\end{tabular}


\subsection*{index.ejs}
\begin{boxedverbatim}
<h2>Neuen Eintrag anlegen</h2>
<form action = "/" method="POST">
    <input type="text" name = "text" placeholder="Bitte neue Aufgabe eingeben" />
    <input type="submit" value="Neu" />
</form>
\end{boxedverbatim}

\subsection*{index.js}
\begin{boxedverbatim}
const bodyParser= require('body-parser');
app.use(bodyParser.urlencoded({extended: true}));
...
app.post('/', function(req, res){
    console.log(req.body);
});
\end{boxedverbatim}

\section{Neue Datensätze in MongoDB speichern}
\subsection*{index.js}
\begin{boxedverbatim}
...
app.post('/', function(req, res){
    db.collection('aufgaben').save(req.body, function(err, result){
        if (err) return console.log(err);
        res.redirect('/');
    });
});
\end{boxedverbatim}

\section{Löschen-Button im Formular}
\subsection*{index.ejs}
\begin{boxedverbatim}
<h1>Todoliste</h1>
<ul>
    <% liste.forEach(function(aufgabe) { %>
        <li><%= aufgabe.text %>
            <form action="/delete" method="POST">
                <input type="hidden" name="id" value="<%= aufgabe._id %>">
                <input type="submit" value="Löschen" />
            </form>
        </li>
    <% }); %>
</ul>
...
\end{boxedverbatim}

\section{Datensatz in MongoDB löschen}
\subsection*{index.js}
\begin{boxedverbatim}
var ObjectId = require('mongodb').ObjectID;
...
app.post('/delete', function(req, res){
    var id = req.body.id;
    var aufgabe = { _id: ObjectId(id)};
    db.collection('aufgaben').remove(aufgabe, function(err, result){ 
        if (err) return console.log(err);
        res.redirect('/');
    });
});
\end{boxedverbatim}

\section*{Quellen}
\begin{itemize}
\item \href{https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction}{MDN: Express/Node introduction}
\item \href{https://zellwk.com/blog/crud-express-mongodb/}{Building a Simple CRUD Application with Express and MongoDB}
\end{itemize}
\end{document}
