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

  • 299