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...
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
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'))
// 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
const PersonClass = require('./obj/person.class')
const PersonFN = require('./obj/person.fn')
let p1 = new PersonClass('kian')
let p2 = new PersonFN('asqar')
let Person = {
setName: (aName) => { name = aName },
say: () => {
console.log(`Hi!, I am ${name}`)
}
}
module.exports = Person
let singletonPerson = require('./obj/person.module')
singletonPerson.say()
singletonPerson.setName('sth')
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)
})
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.createServer => has an event named `request`
`request` event has parameters:
request <http.IncomingMessage>
response <http.ServerResponse>
See http.IncomingMessage
It's a ReadableStream
See http.ServerResponse
const serverRoutes = {
'GET': [
{
path: '/',
handler: (req, resp, body) => { ... }
},
{
path: '/yo',
handler: (req, resp, body) => { ... }
}
]
}
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!')
})
New request
fn(req, resp, next)
fn(req, resp, next)
fn(req, resp, next)
$ 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()
// 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
// 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
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)
// 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) => {})
})
module:
my-app
ctrl:
homeCtrl
template:
home
template:
profile
ctrl:
profileCtrl
service:
taskModel
directive:
taskFilter
<!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>
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
Add an authentication to our app
Fron-end
Back-end
Fix some issues with folder structure and learn about best practices