Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Vorlesungsfolien Web Engineering II

Vorlesungsfolien Web Engineering II

Christian Liebel

December 09, 2020
Tweet

More Decks by Christian Liebel

Other Decks in Science

Transcript

  1. 1. Language 2. Comments 3. Variables 4. Literals 5. Property

    Access Expressions 6. Property Assignment 7. Operators 8. Functions 9. Prototypen 10.Control Structures 11. Promises 12. Modules 13. TypeScript Agenda Web Engineering II JavaScript Intro
  2. History Created as “LiveScript” in 1995 by Brendan Eich Purpose:

    Dynamic form validation, Java applet communication (Netscape Communicator 2.0) To profit from Java’s popularity, LiveScript was renamed to JavaScript (there are no technical relations whatsoever) Language Web Engineering II JavaScript Intro
  3. Properties Multiparadigm (object-oriented, functional, procedural) Typing - Weak: Allows implicit

    type conversions - Dynamic: Type checks during runtime - Duck Typing: Type is not determined by class, but by object shape (methods, properties) Language Web Engineering II JavaScript Intro
  4. Data Types Primitives Boolean (true/false) Number (IEEE 754, “double”) BigInt

    (arbitrarily large integer) String (Unicode) Null (no value) Undefined (not defined) Symbol (unique atomic value) Object Language Web Engineering II JavaScript Intro
  5. Standardization Ecma International Technical Committee 39 – ECMAScript ECMAScript 262

    Time-based Release Schedule Current version: ECMAScript 2020 Language Web Engineering II JavaScript Intro
  6. The most simple language construct Explains/documents code // Line comment

    /* Block comment, multi-line */ Comments Web Engineering II JavaScript Intro
  7. JSDoc /** * Multiplies two numbers. * @param {number} a

    factor * @param {number} b factor */ function multiply(a, b) { return a * b; } Comments Web Engineering II JavaScript Intro
  8. Declaration Symbolic name for a value // Declared with let

    let x; // Assign values via “=” x = 3; let y = 4; Note: The return value of an assignment (without declaration) is the value itself! Variables Web Engineering II JavaScript Intro
  9. Declaration // Declared with const const z = 5; z

    = 6; // TypeError: Assignment to constant variable. Be careful: Only the assignment is constant! Variables Web Engineering II JavaScript Intro
  10. Evaluation Symbolic name for a value // Evaluate values by

    specifying the variable name let y = 3; y; // 3 Variables Web Engineering II JavaScript Intro
  11. Types Variables have no type declaration However, you should avoid

    assigning different types if possible let y; y = 3; y = 'Peter'; Variables Web Engineering II JavaScript Intro
  12. $ node > let x; > x; // Result? >

    x = 3; > x = 'Peter'; > x; // Result? > const y = 4; > y = 5; > y; // Result? Variables LAB #1 Web Engineering II JavaScript Intro
  13. $ node > let x; > x; // undefined >

    x = 3; > x = 'Peter'; > x; // 'Peter' > const y = 4; > y = 5; // TypeError > y; // 4 Variables LAB #1 Web Engineering II JavaScript Intro
  14. Why no var? var x = 3; if (true) {

    var x = 4; } x; // ? let x = 3; if (true) { let x = 4; } x; // ? Variables Web Engineering II JavaScript Intro
  15. Why no var? var x = 3; if (true) {

    var x = 4; } x; // 4 let x = 3; if (true) { // block scoped let x = 4; } x; // 3 Variables Web Engineering II JavaScript Intro
  16. Basic // Numbers 12 1.2 1_234_567.89 // BigInt 10_000_000_000_000_000n //

    Boolean true false // Null null // Strings "x" 'x' `x` // Regular Expressions /[0-9]x/ Literals Web Engineering II JavaScript Intro
  17. Complex // Object initializer {} { a: 3, b: "test"

    } { "a": 3, "b": "test" } Properties “a” and “b” are called keys “3” and “test” are called values Literals Web Engineering II JavaScript Intro
  18. Complex // Array initializer [] [1, 2, 3] [ 1,

    2, 3, ] “1”, “2”, “3” are called elements Literals Web Engineering II JavaScript Intro
  19. Define… - an array - containing two objects - each

    defining - a name - an age Literals LAB #2 Web Engineering II JavaScript Intro
  20. [{ name: 'Peter', age: 17 }, { name: 'Astrid', age:

    31 }] Literals LAB #2 Web Engineering II JavaScript Intro
  21. Template Strings // Strings "x" 'x' `x ${expression}` `1+3 is

    ${1+3}` // Logging your name to the console const name = 'Alfred'; console.log(`Your name is ${name}`); Literals Web Engineering II JavaScript Intro
  22. Elements const persons = [{ name: 'Peter', age: 17 },

    { name: 'Astrid', age: 31 }]; // How to get Astrid? Property Access Expressions Web Engineering II JavaScript Intro
  23. Elements const persons = [{ name: 'Peter', age: 17 },

    { name: 'Astrid', age: 31 }]; // Square bracket notation persons[1]; // { name: 'Astrid', age: 31 } // (Destructuring assignment) const [, astrid] = persons; astrid; // { name: 'Astrid', age: 31 } Property Access Expressions Web Engineering II JavaScript Intro
  24. Properties const astrid = { name: 'Astrid', age: 31 };

    // How to get the name? Property Access Expressions Web Engineering II JavaScript Intro
  25. Properties const astrid = { name: 'Astrid', age: 31 };

    // Dot notation astrid.name; // 'Astrid' // Square bracket notation astrid['name']; // 'Astrid' // (Destructuring assignment) const { name } = astrid; name; // 'Astrid' Property Access Expressions Why would you want to use this? Web Engineering II JavaScript Intro
  26. Properties // Programmatic access const key = 'name'; astrid[key]; //

    Names not allowed as an identifier const astrid = { "foo.bar": 3, "!": 4 } astrid['foo.bar']; // 3 astrid['!']; // 4 Property Access Expressions Web Engineering II JavaScript Intro
  27. const persons = [{ name: 'Peter', age: 17 }, {

    name: 'Astrid', age: 31 }]; 1. Get Peter and store as variable “p” using square bracket notation 2. Get his age from the variable using dot notation 3. Get Peter using a destructuring assignment 4. Get Astrid’s name by only using the square bracket notation Property Access Expressions LAB #3 Web Engineering II JavaScript Intro
  28. const persons = [{ name: 'Peter', age: 17 }, {

    name: 'Astrid', age: 31 }]; 1. Get Peter and store as variable using square bracket notation const peter = persons[0]; 2. Get his age from the variable using dot notation peter.age; 3. Get Peter using a destructuring assignment const [ peter ] = persons; 4. Get Astrid’s name by only using the square bracket notation persons[1]['name']; Property Access Expressions LAB #3 Web Engineering II JavaScript Intro
  29. undefined // Accessing properties that do not exist return undefined

    const object = { a: 3 } object.b; // undefined object.b.x; // TypeError: Cannot read property 'x' of undefined You cannot read properties from null or undefined! Be careful: undefined is not a reserved keyword! Property Access Expressions Web Engineering II JavaScript Intro
  30. Updating Properties const astrid = { name: 'Astrid', age: 31

    }; astrid.age = 32; astrid['age'] = 32; Property Assignment Web Engineering II JavaScript Intro
  31. Creating Properties const astrid = { name: 'Astrid', age: 31

    }; astrid.lastName = 'Müller'; astrid['!'] = 3.14159; Property Assignment Web Engineering II JavaScript Intro
  32. (Deleting Properties) const astrid = { name: 'Astrid', age: 31

    }; delete astrid.age; astrid; // { name: "Astrid" } Property Assignment But wait. This is const? Web Engineering II JavaScript Intro
  33. Const objects const astrid = { name: 'Astrid', age: 31

    }; astrid.age = 32; astrid['!'] = 3.14159; const does not mean that the object is immutable! Only the reference to the object is immutable, i.e. astrid can’t be redefined to point to a different object. Properties can be updated, created or deleted. delete astrid.age; Property Assignment Web Engineering II JavaScript Intro
  34. Arrays const alphabet = ['a', 'p']; // Update property alphabet[1]

    = 'b'; // Add property alphabet[2] = 'c'; alphabet[25] = 'z'; Property Assignment Web Engineering II JavaScript Intro
  35. > const persons = []; > persons; 1. Add a

    new (empty) object literal as the first element of the persons array 2. Update the object literal to have a name property set to Peter 3. Update the name property to contain Astrid instead Property Assignment LAB #4 Web Engineering II JavaScript Intro
  36. > const persons = []; > persons; 1. Add a

    new (empty) object literal as the first element of the persons array persons[0] = {}; 2. Update the object literal to have a name property set to Peter persons[0].name = 'Peter'; 3. Update the name property to contain Astrid instead persons[0].name = 'Astrid'; Property Assignment LAB #4 Web Engineering II JavaScript Intro
  37. Basic Maths // Add 3 + 2 // Subtract 5

    - 2 // Multiply 3 * 7 // Divide 25 / 5 // Remainder 10 % 4 Operators Web Engineering II JavaScript Intro
  38. Shorthand Operators // Add let i = 0; i +=

    3; // 3 // Subtract let i = 5; i -= 2; // 3 // Multiply let i = 2; i *= 3; // 6 // Divide let i = 25; i /= 5; // 5 Operators Web Engineering II JavaScript Intro
  39. Shorthand Operators // Increment let i = 0; let j

    = i++; // i = 1, j = 0 // Decrement let i = 5; let j = i--; // i = 4, j = 5 // Increment let i = 0; let j = ++i; // i = 1, j = 1 // Decrement let i = 5; let j = --i; // i = 4, j = 4 Operators Web Engineering II JavaScript Intro
  40. // String Concatenation "Ha" + "llo!" // "Hallo!" // Bitshifting

    1 << 2 // 4 // Number conversion +"3" // 3 Operators Web Engineering II JavaScript Intro
  41. > const point = { x: 1, y: 20 };

    > const delta = { x: 3, y: -9 }; You received two objects, one describing the original mouse position, the other an object that describes how far the mouse was moved. What’s the new x and y position of the mouse? const newPoint = { /* … */ }; Operators LAB #5 Web Engineering II JavaScript Intro
  42. > const point = { x: 1, y: 20 };

    > const delta = { x: 3, y: -9 }; You received two objects, one describing the original mouse position, the other an object that describes how far the mouse was moved. What’s the new x and y position of the mouse? const newPoint = {x: point.x + delta.x, y: point.y + delta.y}; // { x: 4, y: 11 } Operators LAB #5 Web Engineering II JavaScript Intro
  43. Relational // Greater than 4 > 3 // Greater than

    or equal to 4 >= 3 // Less than 4 < 3 // Less than or equal to 4 <= 3 Operators Web Engineering II JavaScript Intro
  44. Equality // Equality 3 == 3 // Inequality 4 !=

    3 Operators Web Engineering II JavaScript Intro
  45. Abstract Equality In your node REPL console, try the following:

    > 3 == 3 > "3" == 3 > [1] == 1 > 1 == true > 100 == true > NaN == NaN What’s the result? What did you expect? Operators LAB #6 Web Engineering II JavaScript Intro
  46. Strict Equality In your node REPL console, try the following:

    > 3 === 3 > "3" === 3 > [1] === 1 > 1 === true > 100 === true > NaN === NaN What’s the result? What did you expect? Operators LAB #7 Web Engineering II JavaScript Intro
  47. Logical // AND 3 === 3 && 2 === 2

    // OR false || !false Operators Web Engineering II JavaScript Intro
  48. Inversion // Inversion !true !false !!true !!false !!"" !!"test" !!0

    !!1 !!NaN !!null !!undefined Operators LAB #8 Web Engineering II JavaScript Intro
  49. Truthy vs. Falsy The following values evaluate to false: -

    false - 0 - null - undefined - NaN - "" (empty string) All other values evaluate to true. Operators Web Engineering II JavaScript Intro
  50. function add(x, y) { return x + y; } function

    boom() { throw new Error('boom'); } - Can have a name - Can have parameters - Can return a result (or undefined) - Can throw errors Functions Web Engineering II JavaScript Intro
  51. First-Class Citizens const add = function (x, y) { return

    x + y; }; add(1, 3); // 4 const person = {name: 'Peter'}; person.greet = function () { return `Hallo ${this.name}`; } person.greet(); // 'Hallo Peter' Can be used in any context, e.g. as object methods (greet) Functions Web Engineering II JavaScript Intro
  52. Constructor Functions function Person(name) { this.name = name; } const

    peter = new Person('Peter'); peter.name; // 'Peter' The only functions that may have an uppercase identifier (important convention) Instances can be created via new Functions Web Engineering II JavaScript Intro
  53. Classes (Syntactic Sugar Over C’tor Functions) function Person(name) { this.name

    = name; } const peter = new Person('Peter'); peter.name; // 'Peter' class Person { constructor(name) { this.name = name; } } const peter = new Person('Peter'); peter.name; // 'Peter' Functions Web Engineering II JavaScript Intro
  54. this The this context may vary depending on usage: -

    Global Context - Instance creation via new - Context of the caller - Virtually any value the function was bound to or called with This can cause problems. Functions Web Engineering II JavaScript Intro
  55. this function test() { this.name = 'Alfred'; return { getName:

    function () { return this.name; } } } test().getName(); // ??? Functions LAB #9 Web Engineering II JavaScript Intro
  56. this function test() { this.name = 'Alfred'; return { getName:

    function () { return this.name; } } } test().getName(); // undefined Functions LAB #9 Web Engineering II JavaScript Intro
  57. Fat Arrow Functions // Classic form const fn1 = function(y)

    { return y; }; fn1(1); // 1 // Shorthand form const fn2 = y => y; fn2(1); // 1 Functions Web Engineering II JavaScript Intro
  58. Fat Arrow Functions () => console.log('xyz'); a => console.log(a); (a,

    b) => a + b; (a, b) => { const c = 123; return a + b + c; } () => ({ a: 123 }) No parameters = parentheses Single parameter = no parentheses Implicit return Curly braces = custom return/throw Return object = parentheses around curly braces Functions Web Engineering II JavaScript Intro
  59. Fat Arrow Functions function test() { this.name = 'Alfred'; return

    { getName: () => this.name }; } test().getName(); // ??? Functions LAB #10 Web Engineering II JavaScript Intro
  60. Fat Arrow Functions function test() { this.name = 'Alfred'; return

    { getName: () => this.name }; } test().getName(); // Alfred this context is maintained Functions LAB #10 Web Engineering II JavaScript Intro
  61. Higher-Order Functions As JavaScript functions are first-class citizens, they can…

    return functions function getMultiplier(multiplier) { return x => x * multiplier; } getMultiplier(10)(3); // 30 Functions Closure Web Engineering II JavaScript Intro
  62. Higher-Order Functions As JavaScript functions are first-class citizens, they can…

    take other functions as arguments (e.g. callbacks) requestData(data => /* … */); [1, 2, 3].filter(value => value >= 2); Functions Web Engineering II JavaScript Intro
  63. Higher-Order Functions What do these higher-order array functions do? [1,

    2, 3].forEach(elm => console.log(elm)); [1, 2, 3].map(elm => elm * 2); [1, 2, 3].filter(elm => elm >= 2); [1, 2, 3].reduce((acc, curr) => acc + curr); Functions LAB #11 Web Engineering II JavaScript Intro
  64. Higher-Order Functions What do these higher-order array functions do? [1,

    2, 3].forEach(elm => console.log(elm)); // Iteration [1, 2, 3].map(elm => elm * 2); // Manipulation [1, 2, 3].filter(elm => elm >= 2); // Filtering [1, 2, 3].reduce((acc, curr) => acc + curr); // Accumulation Functions LAB #11 Web Engineering II JavaScript Intro
  65. Closure function getGreeter() { const greet = 'Hi '; return

    function(name) { console.log(greet + name); } } const greeter = getGreeter(); greeter('Tom'); // ??? Functions Web Engineering II JavaScript Intro
  66. Closure function getGreeter() { const greet = 'Hi '; return

    function(name) { console.log(greet + name); } } const greeter = getGreeter(); greeter('Tom'); // "Hi Tom" Inner function can access variables from outer scope Closure = function + enclosing context (during creation) greet is hidden inside after creation (“private”) Functions Web Engineering II JavaScript Intro
  67. Closure function getGreeter(greet) { return function(name) { console.log(greet + name);

    } } const greeter1 = getGreeter('Hi '); const greeter2 = getGreeter('Yo '); // Let them greet… Functions Web Engineering II JavaScript Intro LAB #12
  68. Generator Functions function* generator(number) { yield 1; yield 10 *

    number; } const gen = generator(10); console.log(gen.next().value); // 1 console.log(gen.next().value); // 100 Functions Web Engineering II JavaScript Intro
  69. Prototypes Web Engineering II JavaScript Intro function Person(name) { this.name

    = name; } /* * How to add a shared instance method? */ const alfred = new Person('Alfred');
  70. Prototypes Web Engineering II JavaScript Intro function Person(name) { this.name

    = name; } Person.prototype.sayHello = function () { console.log(`Hi, call me ${this.name}`); }; const alfred = new Person('Alfred'); alfred.sayHello();
  71. Inheritance Prototypes Web Engineering II JavaScript Intro function Person() {

    this.walk = () => console.log('I can walk.'); } function Student() { Person.call(this); this.drink = () => console.log('I can drink.'); } Student.prototype = Object.create(Person.prototype); Student.prototype.constructor = Student;
  72. Inheritance function Person() { this.walk = () => console.log('I can

    walk.'); } function Student() { Person.call(this); this.drink = () => console.log('I can drink.'); } Student.prototype = Object.create(Person.prototype); Student.prototype.constructor = Student; const student = new Student(); student.drink(); student.walk(); student instanceof Student student instanceof Person student.__proto__ student.__proto__.__proto__.… Prototypes Web Engineering II JavaScript Intro LAB #13
  73. Inheritance Prototypes Web Engineering II JavaScript Intro class Person {

    walk() { console.log('I can walk.'); } } class Student extends Person { constructor() { super(); } drink() { console.log('I can drink.'); } }
  74. Inheritance class Person { walk() { console.log('I can walk.'); }

    } class Student extends Person { constructor() { super(); } drink() { console.log('I can drink.'); } } const student = new Student(); student.drink(); student.walk(); student instanceof Student student instanceof Person student.__proto__ student.__proto__.__proto__.… Prototypes Web Engineering II JavaScript Intro LAB #14
  75. Takeaways Prototypes Web Engineering II JavaScript Intro JavaScript inheritance is

    based on prototypes New class/extends keywords and constructor/super calls are only syntactical sugar over prototypes Prefer classes
  76. if if (condition) { // do x } else if

    (condition2) { // do y } else { // do z } Control Structures Web Engineering II JavaScript Intro
  77. switch switch (value) { case 1: // do something break;

    case 2: // do a different thing break; default: // do default; } Control Structures Web Engineering II JavaScript Intro
  78. for for (let i = 0; i < 50; i++)

    { // do 50-times… } Control Structures Web Engineering II JavaScript Intro
  79. for const obj = { a: 1, b: 2 };

    for (let x in obj) { // for each property in obj } Object.keys(obj) .forEach(x => /* … */) (nur für eigene Eigenschaften) const arr = [1, 2, 3]; for (let x of arr) { // for each element of arr } arr.forEach(x => /* … */); Control Structures Web Engineering II JavaScript Intro
  80. do…while let n = 0; do { console.log(n); n++; }

    while (n < 2); Control Structures Web Engineering II JavaScript Intro
  81. while let n = 0; while (n < 2) {

    console.log(n); n++; // break; // continue; } Control Structures Web Engineering II JavaScript Intro
  82. try…catch try { throw new Error('boom'); } catch (err) {

    console.log('Caught ' + err); } Control Structures Web Engineering II JavaScript Intro
  83. Automatic Semicolon Insertion (ASI) return; { a: 3 }; Be

    careful: JavaScript automatically inserts semicolons in some cases. Hence, it’s convention to always place braces in the same line. Control Structures Web Engineering II JavaScript Intro
  84. Callbacks Promises Web Engineering II JavaScript Intro httpService.get('https://example.com/customers', customers =>

    { // I know my customers now! }, err => { // Something bad has happened! }); Well-known model for handling asynchronous operations “When the operation is done, call this function.”
  85. Callbacks Promises Web Engineering II JavaScript Intro httpService.get('https://example.com/customers', customers =>

    { inputService.ask('Welchen Kunden löschen?', customers, selection => { httpService.delete(`https://example.com/items/${selection}`, () => { alert(`Kunde ${selection} erfolgreich gelöscht!`); }); }); });
  86. “Pyramid of Doom” Promises Web Engineering II JavaScript Intro httpService.get('https://example.com/customers',

    customers => { inputService.ask('Welchen Kunden löschen?', customers, selection => { httpService.delete(`https://example.com/items/${selection}`, () => { alert(`Kunde ${selection} erfolgreich gelöscht!`); }); }); });
  87. “Callback Hell” Promises Web Engineering II JavaScript Intro httpService.get('https://example.com/customers', customers

    => { inputService.ask('Welchen Kunden löschen?', customers, selection => { httpService.delete(`https://example.com/items/${selection}`, () => { alert(`Kunde ${selection} erfolgreich gelöscht!`); }, err => { console.error(`Could not delete ${selection}!`); }); console.log(`Successfully triggered deletion of ${selection}!`); }); }, err => { console.error(`Could not fetch list! ${err}`); });
  88. Callbacks 2.0 Promises Web Engineering II JavaScript Intro A Promise

    represents a future value (resolved asynchronously) (In the future) the operation can either succeed or it can fail Promises can be composed in an easy manner
  89. Terminology Promises Web Engineering II JavaScript Intro State Operation… Pending

    is in progress Fulfilled was successfully completed Rejected has failed Settled is either fulfilled or rejected
  90. Composition Promises Web Engineering II JavaScript Intro time à long-running

    operation rejected fulfilled short op. rejected fulfilled fulfilled long-running operation rejected fulfilled fulfilled unhandled promise rejection
  91. Chaining Promises Web Engineering II JavaScript Intro Handler Promise… then

    has resolved (+value) catch has failed (+error) finally (ES 2018) has settled
  92. Usage httpService.get('https://example.com/customers') .then(customers => { return inputService.ask('Welchen Kunden löschen?', customers);

    }, err => { console.error(`Could not fetch list! ${err}`); }).then(selection => { console.log(`Successfully triggered deletion of ${selection}!`); return httpService.delete(`https://example.com/items/${selection}`); }).then(() => { alert('Successfully deleted!'); }, err => { console.error('Unable to delete.'); }); JavaScript Intro Web Engineering II Promises
  93. Convenience Methods Promises Web Engineering II JavaScript Intro State Operation…

    Promise.all([p1, p2, p3]) resolves when all inner promises have been resolved Promise.race([p1, p2, p3]) resolves/rejects when the first inner promise resolves/rejects Promise.reject(new Error('boom')) wrap synchronous value in immediately rejected promise Promise.resolve({ result: 123 }) wrap synchronous value in immediately resolved promise
  94. Error Handling Promise.resolve(true) .then(value => { return Promise.reject('boom'); }).then(() =>

    { // This then block is only called if the previous op. was successful }).catch(err => { // This catch block catches any previous error, otherwise it's skipped // If it doesn’t reject, execution continues with the next then block return 'test'; }).then(value => { throw new Error(value); // What’s value here? }).finally(() => { // Must appear at last. Doesn’t get value/error, can’t manipulate result }); JavaScript Intro Web Engineering II Promises
  95. Please try in a browser! StarWars API: https://swapi.dev Fetch a

    single character, planet or starship of your choice! fetch('https://swapi.dev/…') fetch returns a promise wrapping the response. This has a json method for converting the response to JSON (again returns a promise): response.json() alert(`Hello I am ${obj.name}`); Promises Web Engineering II JavaScript Intro LAB #15
  96. Please try in a browser! fetch('https://swapi.dev/api/planets/1') .then(response => response.json()) .then(planet

    => alert(`Hello my name is ${planet.name}`)); Promises Web Engineering II JavaScript Intro LAB #15
  97. Now, add error handling (i.e. in case the network is

    down) Promises Web Engineering II JavaScript Intro LAB #16
  98. fetch('https://swapi.co/api/planets/1') .then(response => response.json()) .then(planet => alert(`Hello my name is

    ${planet.name}`)) .catch(err => alert(`Oh no: ${err}`)); Promises Web Engineering II JavaScript Intro LAB #16
  99. async/await (ES 2017) Promises Web Engineering II JavaScript Intro Syntactial

    sugar over then & catch for using it in a synchronous manner async function getPlanet() { try { const response = await fetch('https://swapi.dev/api/planets/1/'); const planet = await response.json(); alert(`Hello my name is ${planet.name}`); } catch (err) { alert(`Oh no: ${err}`); } } getPlanet();
  100. Custom Promise Promises Web Engineering II JavaScript Intro const x

    = new Promise((resolve, reject) => { setTimeout(() => resolve(), 3000); });
  101. Possible problems Promises Web Engineering II JavaScript Intro • Not

    cancellable • Promise chain is only executed once (can only emit a single value) • Eager, i.e. is executed immediately without checking if somebody is actually interested in the return value • No operators for high-level flow composition • Unhandled promise rejections will terminate Node.js process in the future • Solution: Observables (“Callbacks 3.0”) à Angular
  102. Modules Web Engineering II JavaScript Intro Concept: split up your

    codebase into functional modules instead of one large monolith Often: packages/namespaces/assemblies/… In JavaScript: 1 file = 1 module Introduced in ES 2015 Note: There are different other module systems around (e.g. CommonJS)
  103. import/export keywords Modules Web Engineering II JavaScript Intro export: make

    a member publicly accessible import: consume a member from another file
  104. import/export keywords Modules Web Engineering II JavaScript Intro // math.js

    export function add(a, b) { return a + b; } export function cube(x) { return x ** 3; } // calculator.js import { add } from 'math'; console.log(add(1, 3)); // 4
  105. Exports Modules Web Engineering II JavaScript Intro // Named exports

    export const productName = 'Windows'; // var, let function greet() { console.log('Hi!') }; export { greet as pi, greet }; // Default export (only one per script) export default function cube(x) { return x ** 3 }; export default greet; // Re-exports export * from 'other-file'; export { sum } from 'math';
  106. Imports Modules Web Engineering II JavaScript Intro // Named exports

    import * as math from 'math'; import { test, apple as egg } from 'file'; // Default export (only one per script) import cube from 'cube'; // Side-effect import import 'other-file';
  107. CommonJS Modules Web Engineering II JavaScript Intro (Legacy/different) module system,

    e.g. used by Node.js import ≈ require export ≈ module.exports // cube.js module.exports = function (x) { return x ** 3; } // calculator.js const cube = require('./cube'); cube(3); // 27
  108. CommonJS Modules Web Engineering II JavaScript Intro const cube1 =

    require('./cube'); // ./cube.js const cube2 = require('cube'); // node_modules/cube/index.js Be careful: Node.js and many module bundlers (SystemJS, Webpack) use a dot-slash to distinguish between npm modules (Node.js package manager) and files on the file system. Omitting the file extension is recommended (e.g. when using source-to- source compilers such as TypeScript à Angular)
  109. Open VS Code & create a new folder Modules Web

    Engineering II JavaScript Intro LAB #16 Node <9 Node 9+ Create cube.js and calculator.js Create cube.mjs and calculator.mjs In cube.js, provide a cube function and assign it to module.exports In cube.mjs, provide a cube function as the default export In calculator.js, consume the cube function by require('./cube') In calculator.mjs, consume the cube function by importing it Test your app by running node calculator.js Test your app by running node --experimental-modules calculator.mjs
  110. Benefit: Structuring your JavaScript codebase Modules Web Engineering II JavaScript

    Intro src/ models/ customer.js contract.js calculation/ prices.js taxes.js main/ app.js
  111. Designed by Anders Hejlsberg (C#, Delphi) Superset of JavaScript (all

    valid JS is valid TS) Opt-in static typing TypeScript Compiler is a source-to-source transpiler (target: JavaScript of a given version) Additionally, TypeScript allows you to use (some) Stage 3 features and transpiles them to code understandable by older JavaScript engines (downlevel support). JavaScript Intro Web Engineering II TypeScript
  112. Principle TypeScript Web Engineering II JavaScript Intro // JavaScript (=

    valid TypeScript) function addExtension(value) { const suffix = ".exe"; return "${value}${suffix}"; } // TypeScript (opt-in typing) function addExtension(value: string): string { const suffix: string = ".exe"; return "${value}${suffix}"; }
  113. ECMAScript Feature Stages JavaScript Intro Web Engineering II TypeScript 0

    1 2 3 4 STRAWMAN PROPOSAL DRAFT CANDIDATE FINISHED
  114. https://jskatas.org/ (Bereich „ECMAScript 6“) - Block scope / `let` declaration

    - Block scope / `const` declaration - Object literal / basics - Destructuring / array - Destructuring / object - Class / creation - Template Strings / basics - Arrow functions / basics - Arrow functions / function binding - Generator / creation - Generator / yield expressions - Promise/creation - Promise/chaining `then()` - Promise/the API - Promise/promise.catch() Bonus Exercises Web Engineering II JavaScript Intro
  115. 1. General/History 2. Node.js Package Manager 3. Simple HTTP server

    4. SPA Architecture 5. NestJS 6. Logging 7. AuthZ/AuthN 8. Socket.io 9. Database Access Agenda Web Engineering II Node.js
  116. Server-side runtime platform for JavaScript applications Focus on performance (event-driven

    programming, non-blocking infrastructure for scaling) Based on Google’s JavaScript engine V8 (node-chakracore runs on Microsoft’s Chakra Core engine) Can access native interfaces (e.g. file system, devices) in contrast to the browser Node.js Web Engineering II Node.js
  117. History LiveWire Pro Web (1996) First server-side JavaScript runtime provided

    by Netscape Node.js (2009) Presented by Ryan Dahl at JSConf EU 2009 JavaScript on the Server Web Engineering II Node.js
  118. History Isomorphic (2011) Ability of JavaScript apps to run on

    both the server and the client Isomorphic JavaScript (2013) Future of web apps, same source is used to render on server/client Universal JavaScript (2015) JavaScript that is able to run in any environment JavaScript on the Server Web Engineering II Node.js
  119. Purpose Node.js has its own package manager called Node.js Package

    Manager (npm) Packages can be downloaded from a registry (default: https://registry.npmjs.org) npmjs.org is the largest software marketplace in the world npm packages typically cover a very small functionality (e.g. left-pad) npm makes it very easy to turn your app into a package as well “There’s an npm module for that!” Node.js Web Engineering II Node.js Package Manager
  120. Release Schedule April: Even-numbered versions (v10, v12, v14) October: Odd-numbered

    versions (v11, v13, v15) Even-numbered versions are typically covered by long-term support (LTS) for a period of 18 months After that, the version will enter maintenance support for another 12 months Hence: Even-numbered versions are supported for approx. 3 years, which make them a good choice for server environments https://github.com/nodejs/Release Node.js Web Engineering II Node.js
  121. npm init – Create Packages Interactively creates a new package.json

    by asking a couple of questions This file specifies - name, version, description of your package - entry point of your package - license, author of the package - package dependencies - run scripts - and more… Node.js Web Engineering II Node.js Package Manager
  122. npm init – Create Packages Run npm init in the

    directory where your module files are placed and answer the questions. Node.js Web Engineering II Node.js Package Manager LAB #17
  123. npm install – Installing Packages Packages and their dependencies are

    retrieved from the package registry (typically https://registry.npmjs.org) Node.js packages are placed in a folder called node_modules The package manager has two modes: • Global mode (installs packages to a user-level directory): npm i -g @angular/cli • Local mode (installs packages to the current scope): npm i left-pad npm install installs package dependencies from package.json Node.js Web Engineering II Node.js Package Manager
  124. npm install – Installing Packages Run npm i left-pad What

    has been changed in your package.json? Node.js Web Engineering II Node.js Package Manager LAB #18
  125. npm install – Installing Packages Run npm i left-pad What

    has been changed in your package.json? - New entry dependencies - package name & version number with caret (^) Node.js Web Engineering II Node.js Package Manager LAB #18
  126. Dependency Types 1. dependencies: required dependencies 2. devDependencies: dependencies required

    during development time only (i.e. command-line tools, source-to-source transpilers) 3. peerDependencies: required to be installed by a dependant package 4. optionalDependencies: do not have to be installed Node.js Web Engineering II Node.js Package Manager
  127. Semantic Versioning Given MAJOR.MINOR.PATCH, increment the… - MAJOR version when

    a breaking change is introduced - MINOR version when a backwards-compatible feature is introduced - PATCH when a backwards-compatible bugfix is introduced Plus: Additional labels (e.g. 3.0.0-beta.2+20180413011233) Exception: Major version zero (0.x.y), anything may change anytime. https://semver.org Node.js Web Engineering II Node.js Package Manager
  128. Version Ranges Floating Patch (tilde) "~2.1.3" à 2.1.3, 2.1.4, …

    but not 2.2.0 "2.1.x" Floating Minor (caret, default) "^2.1.3" à 2.1.3, 2.6.4, … but not 3.0.0 "2.x" Node.js Web Engineering II Node.js Package Manager
  129. Version Ranges Complex Range ">=2.1.3“ "^3.0.0 || 5.0.0 – 6.1.2“

    Version Pinning "2.1.3" à this version only Node.js Web Engineering II Node.js Package Manager
  130. npx Executes a command (i.e. binary) from local node_modules, a

    central cache or after installing it Convenient alternative to npm i –g in some cases npx cowsay -s "Yo" Node.js Web Engineering II Node.js Package Manager LAB #19
  131. npm update – Updates Packages Updates installed top-level packages, respecting

    semVer npm update –-dev also processes devDependencies npm update –g updates globally installed packages Node.js Web Engineering II Node.js Package Manager
  132. package-lock.json The package-lock.json keeps track of the actually installed package

    versions in your repository. This allows time travelling through the repository’s history (i.e. when switching back in time, the exact same package versions get installed that were in use back then) In addition, it ensures that both developer and build server use the same package versions. Node.js Web Engineering II Node.js Package Manager
  133. npm publish – Publishing Packages Makes your package accessible on

    the registry (npmjs.org by default) Requires prior login via npm login "private": true prevents accidental publication publishConfig allows specifying a set of whitelisted (private) registries Node.js Web Engineering II Node.js Package Manager
  134. npm run – Run scripts package.json can define serveral run

    scripts for common tasks (e.g. running tests, building the application, deployments) The run scripts are defined in the scripts object: "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, Special scripts: start (npm start), test (npm test) Node.js Web Engineering II Node.js Package Manager
  135. npm run – Run scripts prepublish postinstall postversion pretest poststart

    These scripts are automatically run by Node.js after/before the operation. Node.js Web Engineering II Node.js Package Manager
  136. Joining forces… - Functions as first-class citizens - Fat arrow

    functions - Object literals - Modules Node.js Web Engineering II Simple HTTP Server
  137. Event Emitter Node.js makes use of the Event Emitter pattern

    This pattern clearly separates events and event listeners and turns out to be more practical than callbacks Event emitters can emit multiple events over time http.request(options, response => { response.on("data", data => console.log(data)); }); Node.js Web Engineering II Simple HTTP Server
  138. const { createServer } = require('http'); const server = createServer();

    server.on('request', (req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('Hello world!'); res.end(); }); server.listen(8080); Node.js Web Engineering II Simple HTTP Server
  139. Use Postman to send a GET request to http://localhost:8080 Node.js

    Web Engineering II Simple HTTP Server LAB #21
  140. Node.js Web Engineering II SPA Architecture Server- Logik Web API

    Push Service Web API DBs HTML, JS, CSS, Assets Webserver Webbrowser SPA Client- Logik View HTML/CSS View HTML/CSS View HTML/CSS HTTPS WebSockets HTTPS HTTPS
  141. REST REpresentational State Transfer Dissertation by Roy Fielding (HTTP protocol

    editor) in 2000 Architectural Styles and the Design of Network-based Software Architectures Client-server communication RESTful APIs are stateless Resource representation in XML, HTML, JSON, … https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm Node.js Web Engineering II Web APIs
  142. Resources Anything that can be named Identified via Uniform Resource

    Identifiers (URI), or, more specifically, Uniform Resource Locators (URL) HTTP Verbs define way of access Node.js Web Engineering II Web APIs
  143. HTTP Verbs Verb Action GET Access a resource (read-only). POST

    Creates a new child resource. PUT Updates a given resource. DELETE Deletes a resource. HEAD Checks if the given resource exists. OPTIONS Determines which verbs can be executed on a given resource. Node.js Web Engineering II Web APIs
  144. HTTP Verbs Which HTTP verbs are - idempotent (i.e. can

    be called several times without different outcomes)? - safe (i.e. don’t modify resources)? GET / POST / PUT / DELETE / OPTIONS / HEAD Node.js Web Engineering II Web APIs LAB #22
  145. HTTP Verbs Which HTTP verbs are - idempotent (i.e. can

    be called several times without different outcomes)? GET, PUT, DELETE, OPTIONS, HEAD - safe (i.e. don’t modify resources)? GET, OPTIONS, HEAD GET / POST / PUT / DELETE / OPTIONS / HEAD Node.js Web Engineering II Web APIs LAB #22
  146. Accessing REST Resources GET /books GET /books/978-3-8362-6494-5 POST /books PUT

    /books/978-3-8362-6494-5 DELETE /books/978-3-8362-6494-5 Node.js Web Engineering II Web APIs
  147. Content Negotiation Client communicates format (Accept), charset (Accept-Charset), encoding (Accept-Encoding)

    and language (Accept-Language) via HTTP headers If the server can fulfill the request, it responds with the given format/charset/encoding/language. e.g. https://example.com/people/alfred Same resource, different representations (JSON, XML, etc.) Node.js Web Engineering II Web APIs
  148. HATEOAS Functionality & navigation is entirely defined by the responses

    Node.js Web Engineering II Web APIs LAB #23 GET /accounts/12345 HTTP/1.1 Host: bank.example.com Accept: application/xml ... HTTP/1.1 200 OK Content-Type: application/xml Content-Length: ... <?xml version="1.0"?> <account> <account_number>12345</account_number> <balance currency="usd">100.00</balance> <link rel="deposit" href="https://bank.example.com/accounts/12345?deposit=12345" /> <link rel="withdraw" href="https://bank.example.com/accounts/12345?withdraw=12345" /> <link rel="transfer" href="https://bank.example.com/accounts/12345?transfer=2345" /> <link rel="close" href="https://bank.example.com/accounts/12345?status=close" /> </account>
  149. Frameworks Express: Full-fledged web framework for all kinds of web

    applications including RESTful APIs https://expressjs.com/ NestJS: Framework for building efficient, scalable Node.js server-side applications. Under the hood, Nest makes use of Express. https://docs.nestjs.com/ https://docs.nestjs.com/techniques/performance Node.js Web Engineering II Web APIs with Node.js LAB #24
  150. Overview Framework for building efficient, scalable Node.js server applications Combines

    Node.js + TypeScript NestJS uses Express or Fastify (http/2) under the hood Includes a command-line interface for scaffolding/running/building NestJS backends Heavily borrows from Angular’s architecture (e.g. controllers, pipes, guards, interceptors, dependency injection and more) Node.js Web Engineering II NestJS
  151. Setup npm i -g @nestjs/cli nest new project-name # choose

    npm as package manager cd project-name npm start Postman: GET http://localhost:3000 Git missing? Download it at: https://git-scm.org Node.js Web Engineering II NestJS LAB #25
  152. Decorators Provided by TypeScript Add metadata to a symbol @Controller('greet')

    export class AppController { @Get(':name') getHello(@Param('name') name): string { return `Hallo ${name}!`; } } Node.js Web Engineering II NestJS
  153. Controllers A simple JavaScript class Takes care of request/response handling

    @Controller('greet') export class GreetController { @Get('hello') getHello(): string { return 'Hello!'; } } Node.js Web Engineering II NestJS
  154. Routing Routing controls which controller (method) receives which requests e.g.

    GET /greet/hello @Controller('greet') export class GreetController { @Get('hello') getHello(): string { return 'Hello!'; } } Node.js Web Engineering II NestJS
  155. Routing Routes can be parameterized, parameters start with a colon

    e.g. GET /greet/Alfred @Controller('greet') export class GreetController { @Get(':name') getHello(@Param('name') name): string { return `Hello ${name}!`; } } Node.js Web Engineering II NestJS
  156. Routes @Controller('greet') export class AppController { @Get(':name') getHello(@Param('name') name): string

    { return `Hello ${name}!`; } } Node.js Web Engineering II NestJS LAB #26
  157. Versioned Routes const routes: Routes = [ { path: '/v1',

    module: V1Module }, { path: '/v2', module: V2Module } ]; @Module({ imports: [ RouterModule.forRoutes(routes), V1Module, V2Module ], }) export class ApplicationModule {} https://github.com/shekohex/nest-router Node.js Web Engineering II NestJS
  158. Error Handling RESTful APIs communicate errors by using HTTP status

    codes: - 1xx: Information - 2xx: Successful - 3xx: Redirect - 4xx: Client Error - 5xx: Server Error Node.js Web Engineering II NestJS
  159. Error Handling // Pass response & status code throw new

    HttpException('Forbidden', HttpStatus.FORBIDDEN); // Response objects are serialized throw new HttpException({ text: '403' }, HttpStatus.FORBIDDEN); // Shorthand exceptions throw new ImATeapotException(); Node.js Web Engineering II NestJS
  160. Error Handling Add a new POST endpoint for greet/:name. For

    now, this endpoint should always fail. Use an error that is suitable for communicating that there was a conflict (see https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) Test the endpoint using Postman. Node.js Web Engineering II NestJS LAB #28
  161. Craft an API A TODO item has three properties: -

    id (number, optional for creation) - name (string) - done (boolean) { "id": 0, "name": "Wäsche waschen", "done": true } nest generate class todo Node.js Web Engineering II NestJS LAB #29
  162. Craft an API: nest generate controller todos - Fetching all

    TODOs (GET /todos) - 200 OK + array - Fetching a single TODO (GET /todos/123) - 200 OK + object if it exists or 404 Not Found if it does not exist - Creating new TODOs (POST /todos + object without ID) - 201 Created + created object including ID! - Updates a TODO (PUT /todos/123 + object) - 204 No Content - Deletes a TODO (DELETE /todos/123) - 204 No Content Node.js Web Engineering II NestJS LAB #29
  163. Craft an API Use a Map for storing the items

    and a numeric ID. - Use an auto-incremented ID - map.set(id, elm) sets the element with the given ID - map.get(id) returns/accesses the element with the given ID - map.delete(id) removes the element with the given ID - Array.from(map.values()) returns all elements Node.js Web Engineering II NestJS LAB #29
  164. Configuration const app = await NestFactory.create(ApplicationModule, { logger: false, });

    await app.listen(3000); Node.js Web Engineering II Logging
  165. @Controller('greet') export class GreetController { private readonly _logger = new

    Logger('Greet'); @Get() get() { this._logger.log('Foo'); } } Node.js Web Engineering II Logging LAB #30
  166. Authn primarily deals with user identity: who is this person?

    Is she who she says she is? There are a large number of systems that handle this “checkpoint” level of identity and access management and help to reduce the number of credentials that a user needs to provide, often through single sign-on (or SSO). (https://www.cyberark.com/blog/distinguishing-authn-and-authz/, abgerufen 06.05.2018) Node.js Web Engineering II AuthN
  167. Authz answers a different set questions, for example: what should

    this user or system be allowed to access (authz can manage service-to- service as well as user-to-service permissioning)? An authz platform might determine if a user is a developer, and then grant his/her permission to push source code to a Git repository, but prohibit the user from directly changing the software deployed into the production environment. (https://www.cyberark.com/blog/distinguishing-authn-and-authz/, abgerufen 06.05.2018) Node.js Web Engineering II AuthZ
  168. The combination of username and password rarely expires Leaking the

    password may break other accounts as well Node.js Web Engineering II The Problem…
  169. Token-Based Authentication (TBA) Tokens that authorize the user, but expire

    at some point in the future Leaking the token does not leak the password Allows other means of authentication (Single sign-on, passwordless logins, etc.) Node.js Web Engineering II The Solution…
  170. Open Authorization Open protocol for API authorization Version 2 was

    established in 2012 RFC 6749: “The OAuth 2.0 Authorization Framework” Designed with cross-platform applications and living room devices in mind Node.js Web Engineering II OAuth 2.0
  171. Roles Resource Owner Entity that posesses certain protected resources. Resource

    Server Server storing protected resources (i.e. data). Client Application that wants to access resources from the resource server. Authorization Server Authenticates the resource owner and provides access tokens for a certain scope. Can be identical to the resource server. Node.js Web Engineering II OAuth 2.0
  172. Tokens Access Token Allows access to resources (short-lived). Refresh Token

    Allows reissuing a new access token (long-lived). Node.js Web Engineering II OAuth 2.0
  173. Scopes Can be used to limit the type of access

    (and thus the token’s power) to a resource, e.g. by introducing read-only or read/write permissions Node.js Web Engineering II OAuth 2.0
  174. Flows 1. Authorization Code Grant 2. Implicit Grant 3. Resource

    Owner Password Credentials Grant 4. Client Credentials Grant Node.js Web Engineering II OAuth 2.0
  175. Flows Name an example for this flow (which app type

    could make use of it?) Describe how this flow technically works (any special requirements?) Explain the scenario and the sequence diagram Can refresh tokens be issued? (Why?/Why not?) Are there known vulnerabilities? liebel.io/oauthflow Node.js Web Engineering II OAuth 2.0 LAB #31
  176. SOP Same-Origin Policy Origin: Protocol + host name + port

    number Security feature that protects scripts or other content from accessing sensitive data and/or state Node.js Web Engineering II OAuth 2.0
  177. SOP Reference: https://example.com/index.html a) https://example.com:8080/index.html b) http://example.com/index.html c) https://example.com/images/index.html d)

    https://www.example.com/index.html e) https://username@password:example.com/index.html f) https://example.com/ g) https://example.com/sitemap.xml Node.js Web Engineering II OAuth 2.0 LAB #32
  178. CORS Cross-Origin Resource Sharing Feature for protecting end users Requests

    sent to a different origin have to contain a Access-Control- Allow-Origin header that whitelists the origin where the request originated from Node.js Web Engineering II OAuth 2.0
  179. CORS & NestJS const app = await NestFactory.create(ApplicationModule, { cors:

    true }); const app = await NestFactory.create(ApplicationModule, { cors: { maxAge: 5, origin: ['http://api.myapp.com', 'http://web.myapp.com'], allowedHeaders: ['API-Token'], exposedHeaders: ['API-Token-Expiry'] }}); Node.js Web Engineering II OAuth 2.0
  180. Resource Owner Password Credentials Grant Node.js Web Engineering II OAuth

    2.0 http://www.bubblecode.net/en/2016/01/22/understanding-oauth2/ (abgerufen am 08.05.2018) when client is absolutely trusted
  181. On-line service for identity management (Authentication as a Service) Implements

    OAuth 2.0 and OIDC Management UI Open an account at: https://auth0.com Please create a new application. Node.js Web Engineering II Auth0 LAB #33
  182. JSON Web Token Open standard Established in 2015 RFC 7519

    Securely transmit information between parties as a JSON object Encoded in base64 Can be verified and trusted because it is digitally signed But: Data is not encrypted! Node.js Web Engineering II JWT
  183. Claims Name-value pairs included in the token’s payload JWT claims

    iss – entity that issued this token (issuer) sub – authorized subject aud – audience the token is intended for exp – when does the token expire? nbf – when does the token validity start? (not before) Node.js Web Engineering II JWT
  184. JWK & JWKS JSON Web Key (JWK) A JSON object

    that represents a cryptographic key. The members of the object represent properties of the key, including its value. JSON Web Key Set (JWKS) A JSON object that represents a set of JWKs. The JSON object MUST have a keys member, which is an array of JWKs. Node.js Web Engineering II Token Validation
  185. Middleware export class AuthenticationMiddleware implements NestMiddleware { use(req, res, next)

    { jwt({ secret: expressJwtSecret({ cache: true, rateLimit: true, jwksRequestsPerMinute: 5, jwksUri: 'https://${DOMAIN}/.well-known/jwks.json', }), audience: 'http://localhost:3000', issuer: 'https://${DOMAIN}/', algorithm: 'RS256', } … Node.js Web Engineering II JWT & NestJS
  186. Middleware Update your API to make use of the JWT

    middleware. https://liebel.io/nestauth Section “Defining a Nest.js Middleware” Node.js Web Engineering II JWT & NestJS LAB #34
  187. Usage Update your implementation to serve different todos per user.

    Node.js Web Engineering II JWT & NestJS LAB #35
  188. Identity Layer based on OAuth 2.0 for authentication Scopes: openid

    + profile, email, address, phone User information is enclosed as claims in an ID token Node.js Web Engineering II OpenID Connect
  189. General Implementation of “hollywood principle” (don’t call us, we call

    you) Different transport methods: HTTP Long Polling, WebSockets (based on what’s available on the target platform) https://socket.io Node.js Web Engineering II Socket.io
  190. NestJS npm i --save @nestjs/websockets @nestjs/platform-socket.io npm i --save-dev @types/socket.io

    @WebSocketGateway() export class EventsGateway { @WebSocketServer() server: Server; } https://docs.nestjs.com/websockets/gateways Node.js Web Engineering II Socket.io
  191. Usage const socket = require('socket.io-client')('http://localhost'); socket.on('connect', () => /* TODO

    */)); socket.on('event', data => /* TODO */); socket.on('disconnect', () => /* TODO */)); Node.js Web Engineering II Socket.io
  192. e.g. using Sequelize const Sequelize = require('sequelize'); const sequelize =

    new Sequelize('database', 'username', 'password', { host: 'localhost', dialect: 'mysql'|'sqlite'|'postgres'|'mssql', pool: { max: 5, min: 0, acquire: 30000, idle: 10000 }, operatorsAliases: false }); Node.js Web Engineering II Database Access
  193. e.g. using Sequelize const User = sequelize.define('user', { username: Sequelize.STRING,

    birthday: Sequelize.DATE }); sequelize.sync() .then(() => User.create({ username: 'janedoe', birthday: new Date(1980, 6, 20) })) .then(jane => console.log(jane.toJSON())); Node.js Web Engineering II Database Access
  194. Single-Page Application Framework Angular Server- Logik Web API Push Service

    Web API DBs HTML, JS, CSS, Assets Webserver Webbrowser SPA Client- Logik View HTML/CSS View HTML/CSS View HTML/CSS HTTPS WebSockets HTTPS HTTPS Kickstart Angular
  195. Application Segmentation UI-related components (BookModule) UI-related components (TodoModule) Logic/ infrastructure

    components (BookModule) Logic/ infrastructure components (TodoModule) Angular Kickstart Angular
  196. Cross-Platform Support Angular JS HTML CSS .ipa .exe .app ELF

    .apk .appx Single-Page Web Application Cordova Electron Kickstart Angular
  197. Release Schedule Time-based release schedule (6 months) • March/April: even

    version • September/October: odd version Deprecation Policy • Compatibility to previous major version (1 year) • Long-Term Supported Version (critical fixes/security patches only) • 6.x (Oct 2018–19, 1.5 years in total) Angular Kickstart Angular
  198. Properties • Fat clients (i.e., load everything they need to

    run during bootstrap) • A change of the view does not lead to a server-side page navigation Single-Page Web Applications (SPA) Kickstart Angular
  199. Advantages • Very performant • Works offline • No special

    server requirements (i.e., serving static files is sufficient) Disadvantages • Some logic (i.e., computation- intensive) can only be run on a server (connection required) • Logic is transfered to the client (code can’t be kept secret) Single-Page Web Application (SPA) Kickstart Angular
  200. 1. Please update your installation of the Angular CLI: npm

    i -g @angular/cli 2. Please create a new Angular CLI project: ng new todoApp 3. Run the following command and navigate to http://localhost:4200: ng serve Angular CLI LAB #36 Kickstart Angular
  201. Horizontal Application Segmentation UI-related components (BookModule) UI-related components (TodoModule) Logic/

    infrastructure components (BookModule) Logic/ infrastructure components (TodoModule) Modules Kickstart Angular
  202. Angular Building Blocks UI-related components (BookModule) UI-related components (TodoModule) Logic/

    infrastructure components (BookModule) Logic/ infrastructure components (TodoModule) Modules Components Directives Pipes High-Level Services Low-Level Services Kickstart Angular
  203. @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule ], providers:

    [], bootstrap: [AppComponent] }) export class AppModule { } Modules Components Directives Pipes Modules Services Kickstart Angular
  204. UI references a property on the component instance that should

    be interpolated Or: UI references a method on the component instance that should be called on a certain event Automatically updates UI when the model is updated Keeps presentation and model in sync Data Binding Kickstart Angular
  205. In your freshly created project, navigate to src/app/app.component.html and try

    the following bindings: 1. {{ 'hallo' }} 2. {{ 3 }} 3. {{ 17 + 4 }} 4. {{ '<div>Does this work?</div>' }} 5. {{ alert('boom') }} Bindings LAB #37 Kickstart Angular
  206. Component view (HTML) {{ value }} Component logic (TS) @Component(/*

    … */) export class AppComponent { public value = 'Hello!'; } Bindings Kickstart Angular
  207. Component view (HTML) {{ value }} Component logic (TS) @Component(/*

    … */) export class AppComponent { public value = 'Hello!'; } Bindings LAB #38 Kickstart Angular
  208. Pass data in Bind to a certain property of a

    DOM node or component/directive Property Binding [ ] Kickstart Angular
  209. 1. Declare a new field “color” on your component instance

    and initialize it with a CSS color value (e.g., hotpink) 2. Create a new div element in the AppComponent’s HTML template 3. Bind the value of the field to the background color of the div element Hint: [style.backgroundColor] Property Binding LAB #39 Kickstart Angular
  210. Get data out Bind to a certain event of a

    DOM node or component/directive Event Binding ( ) Kickstart Angular
  211. 1. Implement a new method “onClick” on the component instance

    (it opens an alert box: alert('Hello!')) 2. Create a new button element in the AppComponent’s HTML template 3. Bind the click event of the button to the onClick method Hint: (click)="onClick()" 4. Implement a new method “onMouseMove” on the component instance (it logs to the console) 5. Bind the mousemove event of the button to onMouseMove Event Binding LAB #40 Kickstart Angular
  212. public onClick(): void { alert('Hello!'); } public onMouseMove(): void {

    console.log('Hello!'); } <button (click)="onClick()" (mousemove)="onMouseMove()">Click me.</button> Event Binding LAB #40 Kickstart Angular
  213. Adjust the implementations of onClick and onMouseMove to print the

    coordinates of the mouse (instead of printing Hello!) <button (click)="onClick($event)"></button> Hint: public onClick(event: MouseEvent): void {} Event Binding LAB #41 Kickstart Angular
  214. public onClick(event: MouseEvent): void { alert(event.clientX); } public onMouseMove(event: MouseEvent):

    void { console.log(event.clientX); } <button (click)="onClick($event)" (mousemove)="onMouseMove($event)">Click me.</button> Event Binding LAB #41 Kickstart Angular
  215. UI-related Re-usable Manipulate binding values for the view without changing

    the underlying value (one-way) {{ value | pipe }} UI-related components (BookModule) UI-related components (TodoModule) Logic/ infrastructure components (BookModule) Logic/ infrastructure components (TodoModule) Kickstart Angular
  216. Built-in Pipes • uppercase • lowercase • date • number

    • percent • currency • json Pipes Kickstart Angular
  217. Parameters Pipes can also have parameters delimited by a colon

    {{ value | number:'0.3' }} Pipes Kickstart Angular
  218. Built-in Pipes 1. Adjust your value binding from lab #38

    to be printed as UPPERCASE. 2. Add a new numeric field to your AppComponent. Bind this field to the template using the pipes: • Percent • Currency • Number (showing five decimal places) Example: {{ value | number:'0.3' }} Pipes LAB #42 Kickstart Angular
  219. Built-in Pipes {{ value | uppercase }} à HELLO! {{

    number | percent }} à 300% {{ number | currency }} à $3.00 {{ number | number:'0.5' }} à 3.00000 Pipes LAB #42 Kickstart Angular
  220. Custom Pipes Create a new pipe: ng generate pipe yell

    (or: ng g p yell) 1. Which files have been created by the CLI? 2. What is their purpose? Pipes LAB #43 Kickstart Angular
  221. Parts Files Purpose yell.pipe.ts Pipe class implementation yell.pipe.spec.ts Unit test

    Pipes LAB #43 Please also note the update of the AppModule. Kickstart Angular
  222. Custom Pipes Implement the yell pipe as follows: • The

    yell pipe should suffix the bound value with three exclamation marks. • The developer can optionally pass an argument to override the suffix. {{ value | yell }} à Hello!!!! {{ value | yell:'???' }} à Hello!??? Pipes LAB #44 Kickstart Angular
  223. UI-related Re-usable Custom DOM element HTML Template <app-todo></app-todo> UI-related components

    (BookModule) UI-related components (TodoModule) Logic/ infrastructure components (BookModule) Logic/ infrastructure components (TodoModule) Kickstart Angular
  224. Create a new component: ng generate component todo (or: ng

    g c todo) 1. Which files have been created by the CLI? 2. What is their purpose? Components LAB #45 Kickstart Angular
  225. Parts Files Purpose todo.component.html HTML template todo.component.ts Component class implementation

    todo.component.css Stylesheet todo.component.spec.ts Unit Test Components LAB #45 Please also note the update of the AppModule. Kickstart Angular
  226. 1. Extend your TodoComponent with an Input field called todo.

    2. Add a new myTodo field to the AppComponent which holds a todo object { name: "Wash clothes", done: false, id: 3 } 3. Pass the myTodo object to the todo component from the AppComponent’s template. 4. In the TodoComponent’s template, bind the value of the todo field using the JSON pipe. Input LAB #47 Kickstart Angular
  227. Component Perspective <app-todo (done)="onDone($event)"></app-todo> @Output() public done = new EventEmitter<any>();

    // done.emit(todo); @Output('done') public doneEmitter = new EventEmitter<any>(); Output Kickstart Angular
  228. 1. Extend your TodoComponent with an Output called done. 2.

    Add a button to your TodoComponent and an event binding for the click event of this button. When the button is clicked, emit the done event. Pass the current todo object as the event argument. 3. In the AppComponent’s template, bind to the done event and log the finalized item to the console. @Output() public done = new EventEmitter<any>(); // done.emit(todo); Output LAB #47 Kickstart Angular
  229. <app-todo [style.backgroundColor]="color"></app-todo> @Component({ selector: 'app-todo', /* … */ }) export

    class TodoComponent { @HostBinding('style.backgroundColor') public color = 'hotpink'; } Angular Kickstart HostBinding
  230. <app-todo (click)="onClick()"></app-todo> @Component({ selector: 'app-todo', /* … */ }) export

    class TodoComponent { @HostListener('click') public onClick() {} } Angular Kickstart HostListener
  231. Another feature is the “class” property binding: “class.foo” can be

    bound to a boolean value. If the value is truthy, the class is set. If the value is falsy, the class is removed. 1. Add a HostListener that listens for any click on the host element. 2. Introduce a new boolean field called doneState. 3. Assign a HostBinding to it which sets the done class. 4. The click handler method should toggle the underlying field. 5. Bonus: Adjust the component’s CSS to strikethrough all the text inside the component when the done class is set. HostBinding/HostListener LAB #48 Kickstart Angular
  232. UI-related Re-usable Manipulate styling or behaviour of a DOM element

    Or: Manipulate DOM structure (not covered here) <app-todo myDirective></app-todo> UI-related components (BookModule) UI-related components (TodoModule) Logic/ infrastructure components (BookModule) Logic/ infrastructure components (TodoModule) Kickstart Angular
  233. Create a new component: ng generate directive test (or: ng

    g d test) 1. Which files have been created by the CLI? 2. What is their purpose? Directives LAB #49 Kickstart Angular
  234. Parts Files Purpose test.directive.ts Directive class implementation test.directive.spec.ts Unit Test

    Directives LAB #49 Please also note the update of the AppModule. Kickstart Angular
  235. Create a directive that takes a color as an input

    binding. The directive should set the color of the host element (using a host binding). Angular Kickstart Directives LAB #50
  236. Create another directive that adds a click handler to the

    elements where it’s placed on. Whenever the item is clicked, log a message to the console. Angular Kickstart Directives LAB #50
  237. Goal - DI container is aware of environment - Sets

    up dependencies accordingly - Low Coupling, High Cohesion Angular Kickstart Dependency Injection DI Container My Calculation Mock TaxCalc Germany TaxCalc ELSTER
  238. Dependency Tree - Angular Dependency Injection is type-based - Only

    classes can be used as providers and injectables, as interfaces vanish during TypeScript transpilation - Alternative for non-class dependencies: InjectionTokens - Classes have to be marked as @Injectable if they want to request dependencies - Dependencies can be requested by simply using them as a constructor parameter Angular Kickstart Angular DI
  239. Self-Register as an Application-wide Singleton @Injectable({ providedIn: 'root' }) export

    class TaxCalculation {} Angular Kickstart Angular DI RootInjector Module Component Module Component Module Component Component
  240. Consuming Dependencies @Injectable() export class MyCalculation { constructor(taxCalc: TaxCalculation) {}

    } Throws an error if dependency cannot be resolved! Angular Kickstart Angular DI
  241. Not UI-related Re-usable Contain common (domain-specific) logic Contain infrastructure (non-domain-specific)

    code UI-related components (BookModule) UI-related components (TodoModule) Logic/ infrastructure components (BookModule) Logic/ infrastructure components (TodoModule) Kickstart Angular
  242. Create a new service: ng generate service todo (or: ng

    g s todo) 1. Which files have been created by the CLI? 2. What is their purpose? 3. (How) are they provided in the DI container? Services LAB #51 Kickstart Angular
  243. Preparation 1. Create a new Todo model class: ng generate

    class todo 2. Add the properties: - name (string) - done (boolean) - id (number, optional) Services LAB #52 Kickstart Angular
  244. Service API In your TodoService, add the following methods: -

    create(todo: Todo): Todo - get(todoId: number): Todo - getAll(): Todo[] - update(todo: Todo): void - delete(todoId: number): void Add a very basic, synchronous implementation for getAll, get and create. Services LAB #53 Kickstart Angular
  245. Service Usage - Inject your TodoService into the AppComponent (imports!)

    - Log the list of todos to the console Services LAB #54 Kickstart Angular
  246. UI-related Re-usable Manipulate DOM structure <app-todo *myDirective></app-todo> UI-related components (BookModule)

    UI-related components (TodoModule) Logic/ infrastructure components (BookModule) Logic/ infrastructure components (TodoModule) Kickstart Angular
  247. Multiple conditions <div [ngSwitch]="user.language"> <div *ngSwitchCase="DE">Hallo, {{ user.name }}!</div> <div

    *ngSwitchCase="ES">¡Hola, {{ user.name }}!</div> <div *ngSwitchDefault>Hello, {{ user.name }}!</div> </div> Angular Kickstart *ngSwitchCase <div> <div>¡Hola, {{ user.name }}!</div> </div>
  248. Removes Artificial Nodes From Rendering <ng-container [ngSwitch]="user.language"> <div *ngSwitchCase="DE">Hallo, {{

    user.name }}!</div> <div *ngSwitchCase="ES">¡Hola, {{ user.name }}!</div> <div *ngSwitchDefault>Hello, {{ user.name }}!</div> </ng-container> Angular Kickstart ng-container <div>¡Hola, {{ user.name }}!</div>
  249. Repeat DOM Node <ul> <li>Wash my clothes</li> <li>Tidy up the

    room</li> <li>Mine bitcoin</li> </ul> Angular Kickstart *ngFor [ "Wash my clothes" "Tidy up the room" "Mine bitcoin" ]
  250. Display TODOs In the AppComponent - introduce a new field

    todos and assign the return value of todoService.getAll() to it - bind this field to the view using the *ngFor structural directive and an unordered list (<ul>) with one list item (<li>) for each todo <li *ngFor="let todo of todos"></li> Angular Kickstart *ngFor LAB #56
  251. Do not use an unordered list, but iterate over your

    TodoComponent (app-todo) instead and pass the todo via the todo property binding. Adjust the template of TodoComponent to include: - A checkbox (input) to show the “done” state - A label to show the “name” text <label> <input type="checkbox" [checked]="todo.done"> {{ todo.name }} </label> Angular Kickstart Refactoring Step LAB #57
  252. Motivation Obviously, not all use cases can be solved synchronously

    When we are using our Node.js-based TODO API, this will be an asynchronous task (due to network roundtrip) For a fast and fluid user experience, everything that could potentially take longer than 16ms (=> 60 fps) should be done asynchronously! Angular Kickstart Observables
  253. Motivation Callback Promise Observable Execution Eager Eager Lazy Values Multiple

    Single Multiple Cancellable No No* Yes Composable No Yes Yes Angular Kickstart Observables https://angular.de/artikel/angular2-observables/
  254. Originally known as Reactive Extensions for .NET Open-Source Published for

    JavaScript, Java, … High-Level Flow Composition Provides an Observable implementation Provides operators (map, throttle, …) Angular Kickstart RxJS
  255. Service API Adjust your TodoService to now return Observables and

    upgrade the synchronous value in getAll() to an Observable (via of()). - create(todo: Todo): Observable<Todo> - get(todoId: number): Observable<Todo> - getAll(): Observable<Todo[]> - update(todo: Todo): Observable<void> - delete(todoId: number): Observable<void> Observables LAB #60 Kickstart Angular
  256. Infrastructure service provided by Angular’s @angular/core/http package. Allows setting up

    HTTP Requests using a TypeScript-friendly interface: - get(url) - post(url, data) - put(url, data) - delete(url) Angular Kickstart HttpClient
  257. Add a constructor to TodoService and request an instance of

    HttpClient Use HTTP requests instead of returning synchronous data Angular Kickstart HttpClient LAB #63