Modern
& applicative
"Modern"
features of ES5+ standards
useful tooling
practical patterns
"Applicative"
"real world"
example
REST API
intro into
full-stack web app
JavaScript!
Technology stack
?
?
ES6 ES2015
features
Arrow functions
// before
function add(a, b) {
return a + b;
}
// also now
const add = (a, b) => a + b;
Arrow functions
// before
function add(a, b) {
return a + b;
}
// also now
const add = (a, b) => a + b;
prettier
simpler
... other features
let & const
// before
var name = 'Janek';
name = 'Bartek';
// also now
const name2 = 'Stefcio';
name2 = 'Krzychu'; // TypeError
let age = 33;
age = 23; // OK
let & const
// before
var name = 'Janek';
name = 'Bartek';
// also now
const name2 = 'Stefcio';
name2 = 'Krzychu'; // TypeError
let age = 33;
age = 23; // OK
less confusing
shallow immutability
block scope
Classes
// before
function Person(name) {
this.name = name;
}
// also now
class Person {
constructor(name) {
this.name = name;
}
}
// both cases
const kevin = new Person('Kevin');
Classes
// before
function Person(name) {
this.name = name;
}
// also now
class Person {
constructor(name) {
this.name = name;
}
}
// both cases
const kevin = new Person('Kevin');
"sugar syntaxing"
more unified syntax
Modules
// utils.js
function getUsers() {...}
module.exports = getUsers;
// index.js
const getUsers = require('./utils.js');
import/export
CommonJS
// utils.js
export function getUsers() {...}
// index.js
import { getUsers } from './utils';
Template strings
// before
const name = 'Litwo';
const quote =
name
+ ' Ojczyzno moja! ty jesteś jak zdrowie\n'
+ 'Ile cię trzeba cenić, ten tylko się dowie,\n'
+ 'Kto cię stracił;';
// and now
const name = 'Litwo';
const quote = `
${name} Ojczyzno moja! ty jesteś jak zdrowie
Ile cię trzeba cenić, ten tylko się dowie,
Kto cię stracił;
`;
Spread operator
// before
const names = ['Bartek', 'Piotrek'];
const names2 = names.concat(['Kamil']);
// ... or use some loop
// and now
const names2 = [...names, 'Kamil'];
// same thing with objects:
const newCar = { ...oldCar, year: 2019 };
Destructuring
// before
const hero = {
name: 'Iron Man',
powerLvl: 10,
superpowers: ['FLIGHT']
};
const name = hero.name;
const lvl = hero.powerlvl;
// after
const { name, powerLvl: lvl } = hero;
// the same with arrays:
const iterables = [1, 2, 3, 4, 5];
const [first, second] = iterables;
Map & Set
const map = new Map();
map.set('Jan Kowalski', 2345);
map.has('Jan Kowalski'); // true
map.get('Jan Kowalski'); // 2345
map.clear();
const set = new Set();
set.add(1);
set.add(1);
set.size; // 1
Default param. & rest operator
function greet(name = '') {
return 'Hello ' + name;
}
greet(); // Hello
greet('Andrzej'); // Hello Andrzej
function concat(...words) {
const output = '';
for (const word of words) {
output += word;
}
return output;
}
Promises
&
async / await
Let's go back in time...
To ES5!
Array.prototype.filter()
Array.prototype.map()
const numbers = [42, 1, -5, 344, -25, -2.5];
const positiveNumbers = numbers.filter(nr => nr > 0);
// [42, 1, 344]
const numbers = [42, 1, -5, 344, -25, -2.5];
const doubledNumbers = numbers.map(nr => nr * 2);
// [84, 2, -10, 688, -50, -5]
Array.prototype.forEach()
Array.prototype.find()
const numbers = [42, 1, -5];
number.forEach(nr => console.log(nr));
// 42
// 1
// -5
const numbers = [-42, 1, -5, 344, -25, -2.5];
const firstPositive = numbers.find(nr => nr > 0);
// 1
Array.prototype.some()
Array.prototype.every()
const numbers = [42, 1, -5];
const hasPositiveElements = numbers.some(nr => nr > 0);
// true
const numbers = [42, 1, -5];
const areAllElementsPositive = number.every(nr => nr > 0);
// false
Array.prototype.reduce()
const numbers = [42, 1, -5];
const sum = numbers.reduce((acc, curr) => acc + curr, 0);
// 38
// Type definition
arr.reduce(
callback(accumulator, currentValue[, index[, array]])
[, initialValue]
)
Date API
new Date()
// Sun Jun 30 2019 12:45:18 GMT+0200 (czas środkowoeuropejski letni)
new Date().toUTCString()
// "Sun, 30 Jun 2019 10:46:14 GMT"
new Date().toISOString()
// "2019-06-30T10:46:35.797Z"
Date.parse("Sun, 30 Jun 2019 10:46:14 GMT")
// 1561891574000
new Date("Sun, 30 Jun 2019 10:46:14 GMT")
// Sun Jun 30 2019 12:46:14 GMT+0200 (czas środkowoeuropejski letni)
Date.now()
// 1561891539113
Finally...
We are done with the theory
Our app - Splitwise© clone
Database models
type Status = {
id: UUIDv4;
amount: number;
owner: string | User;
debtor: string | User;
};
type User = {
id: UUIDv4;
name: string;
email: string;
password: string;
};
type Action = {
id: UUIDv4;
description: string;
type: ActionType;
date: Date;
amount: number;
payer: string | User;
debtor: string | User;
};
type ActionType =
'SHOPPING'
| 'BILLS'
| 'TRIP'
| 'RESTAURANT';
Basic requirements for Splitter
1. Viewing payment statuses for user.
2. Viewing history of actions for user.
3. Adding new, editing and deleting actions for user.
4. Registering new user and logging in.
1
2
3
express.js
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
return res.send('Hello World!');
});
app.listen(port, () =>
console.log(`Example app listening on port ${port}!`);
);
LET'S DO IT!
What's next?
NodeJS project
REST API (back-end)
Angular app (front-end)
Converting to TypeScript
Build tool, bundler (Webpack, Gulp)
?
Unit testing (Jasmine, Jest)
e2e testing (Cypress, Pickle)
?
?
GraphQL
?
... basically anything you desire!
?
Building REST API with express.js
By Kajetan Świątek
Building REST API with express.js
- 384