MEAN
STACK
APPLICATIONs
CESA IUST
Winter 2017
UP AND RUNNING WITH
the plan ahead
THE N: Node js
- NodeJS
- runtime
- syntax
- Consensus
- Event driven programming
- Callback functions
- Practical
- FileSystem
- HTTP
- Modules
the plan ahead
THE E: EXPRESS
- Express
- The middleware arch.
THE M: MONGODB
- NOSQL Database
- MongoDB Shell
- mongoose
THE A: ANGULAR
SESSION 1: NODE JS
-
Google V8 powered javascript interpreter in Desktop
-
Support direct C binding
-
Fast (relatively!) and lightweight
-
NO DOM!
-
NPM package manager
-
Used in: Desktop, Mobile, Embedded systems, IOT, etc...
-
The complicated story of Node/ecmaScript versions...
SESSION 1: NODE JS
-
Fastest growing community and ecosystem in history
Syntax (#1.1)
-
Variables: let + var + nothing
-
data types: Number, List, String, Object
-
Functions: named functions, variable functions, anonymous functions
-
flow control: for / while / if
-
Event control: nextTick, timeout, interval
-
JS (node/browser) runs in a single thread
-
Event Loop
-
-
Callback functions
modules (#1.2)
Any file can act as a standalone module
function up (str) {
return str.toUpperCase()
}
function mul (x, y) {
return x * y
}
module.exports = {
mul: mul,
up: up
}
let util = require('./Utilities.js')
console.log(util.up('yo'))
modules (#1.2)
LET'S TALK ABOUT CLASS
// ES6 feature
class Person {
constructor (name) {
this.name = name
}
say () {
console.log(`Hi!, I am ${this.name}`)
}
}
module.exports = Person
// ES5 - more complicated than what you think!
function Person (name) {
this.name = name
this.say = function () {
console.log(`Hi!, I am ${this.name}`)
}
}
module.exports = Person
modules (#1.2)
LET'S TALK ABOUT CLASS
const PersonClass = require('./obj/person.class')
const PersonFN = require('./obj/person.fn')
let p1 = new PersonClass('kian')
let p2 = new PersonFN('asqar')
modules (#1.2)
LET'S TALK ABOUT CLASS
let Person = {
setName: (aName) => { name = aName },
say: () => {
console.log(`Hi!, I am ${name}`)
}
}
module.exports = Person
- You will barely need to use `new` in practice
- Avoid using it and stick to file modules
let singletonPerson = require('./obj/person.module')
singletonPerson.say()
singletonPerson.setName('sth')
file system (#1.3)
const fs = require('fs')
fs.writeFile('./trash.txt', 'yo', (err) => {
if (err) throw err
console.log(`[${err}] saved`)
})
// Avoid this
fs.writeFileSync('./trash.txt', 'yo')
fs.readFile('./trash.txt', (err, data) => {
console.log(err, data)
})
http module (#1.4.1)
Let's see the CODE
var srv = http.createServer()
srv.listen(PORT, '127.0.0.1', () => {
console.log(`HTTP server listening on
port ${srv.address().address}:${srv.address().port}`)
})
srv.on('request', (req, res) => {
res.writeHead(200, {'Content-Type': 'text/plain'})
res.end('okay')
})
http module (#1.4.1)
Let's see the DOC
-
http.createServer => has an event named `request`
-
`request` event has parameters:
-
request <http.IncomingMessage>
-
response <http.ServerResponse>
-
-
See http.IncomingMessage
-
It's a ReadableStream
- has `data` and `end` events
-
-
See http.ServerResponse
http module - challenge (#1.4.2)
complete this server to
-
accept request body
-
route requests based on a static route file
const serverRoutes = {
'GET': [
{
path: '/',
handler: (req, resp, body) => { ... }
},
{
path: '/yo',
handler: (req, resp, body) => { ... }
}
]
}
express (#1.5.1)
let express = require('express')
let app = express()
app.get('/', function (req, res) {
res.send('Hello Express')
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
next week
- Learn about mongodb
- Complete express app to a basic CRUD API
- Scaffold a basic client app with Angular
SESSION 2: Express js investigation #2.1.1
- Notes about express
- Using body-parser to read request body
- the `req` object
- `req.body`, `req.baseUrl`, `req.cookies`, `req.ip`, `req.hostname`, `req.method`, `req.path`, `req.query`
- the `resp` object
- `resp.send()`, `resp.end()`, `resp.redirect()`, `resp.json()`, `resp.sendFile()`, `resp.status()`
- with `sendFile`: using `__dirname`
- with `status`: chaining
- `resp.send()`, `resp.end()`, `resp.redirect()`, `resp.json()`, `resp.sendFile()`, `resp.status()`
SESSION 2: Express js investigation #2.1.1
- Properly use `app.use()`
- Tell me a great way to handle all unknown requests!
- app.use can also be used for authentication
New request
fn(req, resp, next)
fn(req, resp, next)
fn(req, resp, next)
express - challenge (#1.5.2)
- Express is Middleware based
- app.METHOD for a specific method
- app.use for all methods
- each middleware is basically:
- a function with sig. : (req, resp, next) => {}
- will pass the {req, resp} to the next middleware when `next()` is called
write a simple logger middleware
mongodb
- NoSQL
- no more join and table crap
- important terms: Database, Collection, Document
- Schema Free!
- Let's see the commands
mongodb - interactive tutorial
$ show dbs
// use or create new database
$ use mean
// insert a document
$ db.mean.insert({"foo": "yo"})
// find it
$ db.mean.find({})
// what about collections?
$ show collections
// what the hell is `mean` in this code?
$ db.wtf.insert({name: 'kian'})
$ show collections
// let's get rid of it...
$ db.wtf.drop()
mongodb - interactive tutorial
// Let's have some valid (or near valid) data
// insert the name and age of some of the folks around you
$ db.users.insert({"name": "kian", age: 21, id: 92521042})
// THE FIND() method
$ db.<collectionName>.find(
{name: "kian"}, <-- criteria
{}, <-- projection
).limit(2) <-- cursor
$ db.users.find(
{age : { $ge: 20} },
{age: 1}
).limit(2)
// operations like $ge can be found on the website
mongodb - interactive tutorial
// THE update() method
$ db.users.update(
{name: "kian"}, <-- criteria
{$set : {name : "kiana"}}, <-- operation
)
// THE remove method
$ db.users.remove(
{name : "kian"} <-- criteria
)
// Note that adapters often offer other ways for update and remove
// which we will use very soon
mongodb - mongoose module
let mongoose = require('mongoose')
// step 1: connection
mongoose.connect('mongodb://localhost/mean')
let db = mongoose.connection
db.on('error', (err) => { console.log('error with db', err) })
db.once('open', function () {
console.log('DB Connected')
})
// optional step 2: Schema
const Schema = mongoose.Schema
const TaskSchema = new Schema({
title: { type: String, require: true},
done: {type: Boolean}
})
// step3: Model
let TaskModel = mongoose.model('TaskModel', TaskSchema)
mongodb - mongoose module #2.2.1
// create a new object
let aTask = new TaskModel({...})
aTask.save((err) => {})
// get and edit
TaskModel.find({...})
TaskModel.findById(_id, (err, aTask) => {
aTask.title = 'yo'
aTask.save((err) => {})
})
// remove
TaskModel.remove({...})
TaskModel.findById(_id, (err, aTask) => {
aTask.remove((err) => {})
})
- All operations are done using the Model object in mongoose
back to express - crud + spa #2.2.2
- Our app is going to server only one html file, the index.html
- `app.get('/')
- 4 Simple API's for each task:
- Create: `app.post('/task')` -> will create a new task and return it to the user
- Read: `app.get('/task/)` will get the list of all tasks
- Update: `app.put('/task/:taskId')` will update a task's info
- Delete `app.delete('/task/:taskId')` will delete a task
- Assume no authentication and no task <-> user relation for now
basic angular js #2.3.1
- Comprehensive, MVC front end framework
- Main component: angular.module
module:
my-app
ctrl:
homeCtrl
template:
home
template:
profile
ctrl:
profileCtrl
service:
taskModel
directive:
taskFilter
basic angular js #2.3.1
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Yo Express</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootflat/2.0.4/css/bootflat.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<script src="/client/main.js" charset="utf-8"></script>
</head>
<body>
<h1>Our single page application will be serverd here</h1>
</body>
</html>
basic angular js #2.3.1
- main.js is not being served!
- Our web server has no idea what to do with 'GET /client/main.js'
- express static file serve
angular js functionality #2.3.2
-
two way data-binding:
- anything attached to `$scope` inside a controller function
- static: {{ }}
- dynamic: using `ng-model` and `<input>`
- anything attached to `$scope` inside a controller function
- Buttons, functions and more
- any function attached to scope can be used in html
- note that inside <X ng-*="...."> and {{ ... }} we are inside of a controller's territory, no need to mention $scope
- event return values!
- any function attached to scope can be used in html
- Iteration:
- <X ng-repeat='for item in list'> {{ item }} </X>
$http in angular #2.3.3
fooApp.controller('fooCtrl', function($scope, $http) {
$http.<METHOD>('/a/url', {data: 'something'})
.then(
(resp) => {} // response success
(resp) => {} // response fail
)
})
you now know everything you need to complete the basics of our todo-app
$http in angular #2.3.3
next week
-
Add an authentication to our app
-
Fron-end
-
Back-end
-
-
Fix some issues with folder structure and learn about best practices
MEAN-tutorial
By Kian Peymani
MEAN-tutorial
- 676