HTML5 Applications

A presentation at Workshop Notes in June 2017 in 91074 Herzogenaurach, Germany by Bilal Çınarlı

Slide 1

Slide 1

Building HTML5 and JS Applications

Slide 2

Slide 2

Bilal Çınarlı Frontend Architect Software Engineer @Adidas

@bcinarli github.com/bcinarli

bcinarli.com

Slide 3

Slide 3

HTML5 - JS Applications

Slide 4

Slide 4

• What is HTML5 and Applications? • JavaScript Design Patterns • You Might Not Need JavaScript • Rest APIs and its advantages • JavaScript Packages and Dependency Management Content • Gulp, WebPack task managers and module bundlers • Modern JavaScript Coding & ES6 • ReactJS

Slide 5

Slide 5

Slide 6

Slide 6

What is HTML5?

Slide 7

Slide 7

Slide 8

Slide 8

Slide 9

Slide 9

• Giving meaning to structure, semantics are front and center with HTML5.

• A richer set of tags, along with RDFa, microdata, and microformats, are enabling a more useful, data driven web for both programs and your users.

Slide 10

Slide 10

Slide 11

Slide 11

• CSS3 delivers a wide range of stylization and effects, enhancing the web app without sacrificing your semantic structure or performance.

• Additionally Web Open Font Format (WOFF) provides typographic flexibility and control far beyond anything the web has offered before.

Slide 12

Slide 12

Slide 13

Slide 13

• Audio and video are first class citizens in the HTML5 web, living in harmony with your apps and sites .

Slide 14

Slide 14

Slide 15

Slide 15

• Between SVG, Canvas, WebGL, and CSS3 3D features, you're sure to amaze your users with stunning visuals natively rendered in the browser.

Slide 16

Slide 16

Slide 17

Slide 17

• Web Apps can start faster and work even if there is no internet connection.

• The HTML5 App Cache, as well as the Local Storage, Indexed DB, and the File API specifications support storing Web Apps data in client .

Slide 18

Slide 18

Slide 19

Slide 19

• Beginning with the Geolocation API, Web Applications can present rich, device-aware features and experiences.

• Incredible device access innovations are being developed and implemented, from audio/video input access to microphones and cameras, to local data such as contacts & events, and even tilt orientation.

Slide 20

Slide 20

Slide 21

Slide 21

• More efficient connectivity means more real-time chats, faster games, and better communication.

• Web Sockets and Server-Sent Events are pushing data between client and server more efficiently than ever before.

Slide 22

Slide 22

Slide 23

Slide 23

• Make your Web Apps and dynamic web content faster with a variety of techniques and technologies such as Web Workers and XMLHttpRequest 2.

Slide 24

Slide 24

JavaScript Design Patterns

Slide 25

Slide 25

Slide 26

Slide 26

• a design pattern is a general repeatable solution to a commonly occurring problem in software design

• a design pattern isn't a finished design that can be transformed directly into code.

• a design pattern is a description or template for how to solve a problem that can be used in many different situations.

Slide 27

Slide 27

Module Design Pattern

Slide 28

Slide 28

var HTMLChanger

( function () {

var contents

'contents' ;

var changeHTML

function () {

var element

document. getElementById ( 'attribute-to-change' ); element.innerHTML

contents ; }

return { callChangeHTML: function () {

changeHTML() ; console. log ( contents ); } }; })(); HTMLChanger. callChangeHTML ();
// Outputs: 'contents'

console. log (HTMLChanger.contents);
// undefined

Slide 29

Slide 29

Revealing Module Design Pattern

Slide 30

Slide 30

var Exposer

( function () {

var privateVariable

10 ;

var privateMethod

function () { console. log ( 'Inside a private method!' ); privateVariable ++ ; }

var methodToExpose

function () { console. log ( 'This is a method I want to expose!' ); }

var otherMethodIWantToExpose

function () {

privateMethod (); }

return { first: methodToExpose , second: otherMethodIWantToExpose

}; })(); Exposer. first ();
// Output: This is a method I want to expose!

Exposer. second ();
// Output: Inside a private method!

Exposer. methodToExpose (); // undefined

Slide 31

Slide 31

Prototype Design Pattern

Slide 32

Slide 32

var TeslaModelS

function () {

this .numWheels

4 ;

this .manufacturer

'Tesla' ;

this .make

'Model S' ; } TeslaModelS.prototype.go

function () {

// Rotate wheels

} TeslaModelS.prototype.stop

function () {

// Apply brake pads

}

Slide 33

Slide 33

Observer Design Pattern

Slide 34

Slide 34

var Subject

function () {

this .observers

[];

return { subscribeObserver: function (observer) {

this .observers. push (observer); },

unsubscribeObserver: 

function (observer) {

var index

this .observers. indexOf (observer);

if (index

1 ) {

this .observers. splice (index, 1 ); } },

notifyObserver: 

function (observer) {

var index

this .observers. indexOf (observer);

if (index

1 ) {

this .observers[index]. notify (index); } },

notifyAllObservers: 

function () {

for ( var i

0 ; i < this .observers.length; i ++ ){

this .observers[i]. notify (i); }; } }; };

Slide 35

Slide 35

var Observer

function () {

return { notify: function (index) { console. log ( "Observer "

index +

" is notified!" ); } } } var subject

new

Subject (); var observer1

new

Observer (); var observer2

new

Observer (); var observer3

new

Observer (); var observer4

new

Observer (); subject. subscribeObserver (observer1); subject. subscribeObserver (observer2); subject. subscribeObserver (observer3); subject. subscribeObserver (observer4); subject. notifyObserver (observer2); // Observer 2 is notified!

subject. notifyAllObservers (); // Observer 1 is notified! // Observer 2 is notified! // Observer 3 is notified! // Observer 4 is notified!

Slide 36

Slide 36

Singleton Design Pattern

Slide 37

Slide 37

var printer = ( function () {

var printerInstance;

function create () {

function

print () {

// underlying printer mechanics

} 

function

turnOn () {

// warm up, check for paper

} 

return {

  print: 

print , turnOn: turnOn

}; 

}

return { getInstance: function () {

if (!printerInstance) { printerInstance = create (); }

return printerInstance; } };

function Singleton () {

if (!printerInstance) { printerInstance = initialize (); } }; })();

Slide 38

Slide 38

You Might Not Need jQuery

Slide 39

Slide 39

Selecting Elements

Slide 40

Slide 40

// with jQuery var $element = $ ( '.my-class' ); // without jQuery var $element = document. querySelectorAll ( '.my-class' ) ;

Slide 41

Slide 41

Finding Elements

Slide 42

Slide 42

// with jQuery $ ( '.my-class' ). find ( child-element ); // without jQuery var $element = document. querySelector ( '.my-class' ) ; $element. querySelectorAll ( child-element )

Slide 43

Slide 43

Add/Remove Classes

Slide 44

Slide 44

// with jQuery var $element

$ ( '.my-class' ); $element. addClass ( 'new-class' ); $element. removeClass ( 'old-class' ); // without jQuery var $element

document. querySelector ( '.my-class' ) ; $element.classList. add ( 'new-class' ); $element.classList. remove ( 'old-class' );

Slide 45

Slide 45

Get/Set Content

Slide 46

Slide 46

// with jQuery var $element

$ ( '.my-class' ); $element. html (); $ ( '<div>' ). append ($element. clone ()). html (); // without jQuery var $element

document. querySelector ( '.my-class' ) ; $element.innerHTML; $element.outerHTML;

Slide 47

Slide 47

// with jQuery var $element

$ ( '.my-class' ); $element. html ( string ); // without jQuery var $element

document. querySelector ( '.my-class' ) ; $element.innerHTML

string ;

Slide 48

Slide 48

Get/Set Text

Slide 49

Slide 49

// with jQuery var $element

$ ( '.my-class' ); $element. text (); // without jQuery var $element

document. querySelector ( '.my-class' ) ; $element.textContent;

Slide 50

Slide 50

// with jQuery var $element

$ ( '.my-class' ); $element. text ( string ); // without jQuery var $element

document. querySelector ( '.my-class' ) ; $element.textContent = string ;

Slide 51

Slide 51

Event Bindings

Slide 52

Slide 52

// with jQuery var $element

$ ( '.my-class' ); $element. on ( eventName , eventHandler ); $element. off ( eventName , eventHandler ); // without jQuery var $element

document. querySelector ( '.my-class' ) ; $element. addEventListener ( eventName , eventHandler ); $element. removeEventListener ( eventName , eventHandler );

Slide 53

Slide 53

Rest API with JSON

Slide 54

Slide 54

• Primary architectural approach for distributed systems. • REST stands for Representational State Transfer.

• It relies on a stateless , client-server , cacheable communications.

• In most cases it is used with the HTTP protocol .

• RESTful applications use HTTP requests to POST (create), PUT

(create and/or update), GET (e.g., make queries), and DELETE data.

Slide 55

Slide 55

Features

Slide 56

Slide 56

• each HTTP contains all the necessary information to run it

• the client can run the same response for identical requests in the future.

• Objects in REST are always manipulated from the URI.

• Uniform interface

Slide 57

Slide 57

The advantages of REST for development

Slide 58

Slide 58

• Separation between the client and the server

• Visibility, reliability and scalability

• The REST API is always independent of the type of platform or languages

Slide 59

Slide 59

{ " data ": [{ " type ": " articles ", " id ": " 1 ", " attributes ": { " title ": " JSON API paints my bikeshed! ", " body ": " The shortest article. Ever. ", " created ": " 2015-05-22T14:56:29.000Z ", " updated ": " 2015-05-22T14:56:28.000Z " }, " relationships ": { " author ": { " data ": {" id ": " 42 ", " type ": " people "} } } }], " included ": [ { " type ": " people ", " id ": " 42 ", " attributes ": { " name ": " John ", " age ": 80 , " gender ": " male " } } ] }

Slide 60

Slide 60

Single Responsibility Principle

Slide 61

Slide 61

Slide 62

Slide 62

• Every module or class should have responsibility over a single part of the functionality provided by the software . • That responsibility should be entirely encapsulated by the class.

• All its services should be narrowly aligned with that responsibility.

Slide 63

Slide 63

Single Page Application Development

Slide 64

Slide 64

JavaScript Packages & Dependencies

Slide 65

Slide 65

NodeJs

Slide 66

Slide 66

• Node.js is a platform built on Chrome's JavaScript runtime for easily building fast and scalable network applications

Slide 67

Slide 67

Packaging

Slide 68

Slide 68

{ " name ": " demo ", " version ": " 1.0.0 ", " description ": " Demo package.json ", " main ": " index.js ", " dependencies ": { " lodash ": " latest " }, " devDependencies ": {}, " scripts ": { " test ": " echo "Error: no test specified" && exit 1 " }, " author ": " Bilal Cinarli ", " license ": " MIT " }

Slide 69

Slide 69

NPM

Slide 70

Slide 70

• Node Package Manager • Default package manager in NodeJs

Slide 71

Slide 71

Yarn

Slide 72

Slide 72

• Yarn package manager • Deterministic Install with lockfiles

Slide 73

Slide 73

ES5 & ES6 KeyPoints

Slide 74

Slide 74

Slide 75

Slide 75

Variables

Slide 76

Slide 76

• let statement declares a block scope local variable, optionally initializing it to a value

• const cannot change through re-assignment, and it can't be redeclared

Slide 77

Slide 77

function varTest() {

var x

1;

if ( true ) {

var x

2;
// same variable!

console.

log ( x );
// 2 } console. log ( x );
// 2

} function letTest() {

let x

1;

if ( true ) {

let x

2;
// different variable

console.

log ( x );
// 2

} console. log ( x );
// 1

}

Slide 78

Slide 78

var list

document. getElementById ( 'list' ); for ( let i

1; i <= 5; i ++ ) {

let item

document. createElement ( 'li' ); item. appendChild (document. createTextNode ( 'Item '

i)); item.onclick

function ( ev ) { console. log ( 'Item '

i +

' is clicked.' ); }; list. appendChild ( item ); } // to achieve the same effect with 'var' // you have to create a different context // using a closure to preserve the value for ( var i

1; i <= 5; i ++ ) {

var item

document. createElement ( 'li' ); item. appendChild (document. createTextNode ( 'Item '

i)); ( function ( i ){ item.onclick

function ( ev ) { console. log ( 'Item '

i +

' is clicked.' ); }; })( i ); list. appendChild ( item ); }

Slide 79

Slide 79

// define MY_FAV as a constant and give it the value 7 const MY_FAV

7; // this will throw an error MY_FAV

20; // will print 7 console. log ( 'my favorite number is: '

MY_FAV); // trying to redeclare a constant throws an error const MY_FAV

20; // the name MY_FAV is reserved for constant above, so this will also fail var MY_FAV

20; // this throws an error also let MY_FAV

20;

Slide 80

Slide 80

Arrow Function

Slide 81

Slide 81

• An arrow function expression has a shorter syntax than a function expression.

• Does not bind its own this, arguments, super, or new.target.

• These function expressions are best suited for non-method functions, and they cannot be used as constructors.

Slide 82

Slide 82

// without variables const f

() => { return

this ; }; // without curly brackets var arguments

42; var arr

() =>

arguments ; arr (); // 42

Slide 83

Slide 83

// An empty arrow function returns undefined let empty

() => {}; (() =>

'foobar' )();
// Returns "foobar" // (this is an Immediately Invoked Function Expression
// see 'IIFE' in glossary) var simple

a => a

15 ? 15 : a;
simple (16); // 15 simple (10); // 10 let max

(a, b) => a

b ? a : b; // More concise promise chains promise. then (a => { // ... }). then (b => { // ... }); // Parameterless arrow functions that are visually easier to parse setTimeout ( () => { console. log ( 'I happen sooner' );

setTimeout ( () => { // deeper code console. log ( 'I happen later' ); }, 1); }, 1);

Slide 84

Slide 84

Object.assign

Slide 85

Slide 85

• The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object.

• It will return the target object

Slide 86

Slide 86

// copying and object var obj

{ a: 1 }; var copy

Object. assign ({}, obj ); console. log ( copy ); // { a: 1 }

// merging objects var o1

{ a: 1 , b: 1 , c: 1 }; var o2

{ b: 2 , c: 2 }; var o3

{ c: 3 }; var obj

Object. assign ({}, o1 , o2 , o3 ); console. log ( obj ); // { a: 1, b: 2, c: 3 }

Slide 87

Slide 87

function test() {

'use strict' ;

let a

{ b: {c: 4 } , d: { e: {f: 1 } } };

let g

Object. assign ({}, a);

let h

JSON. parse (JSON. stringify (a));

console. log (JSON. stringify (g.d)); // { e: { f: 1 } }

g.d.e

32 ; console. log ( 'g.d.e set to 32.' ); // g.d.e set to 32.

console. log (JSON. stringify (g)); // { b: { c: 4 }, d: { e: 32 } }

console. log (JSON. stringify (a)); // { b: { c: 4 }, d: { e: 32 } }

console. log (JSON. stringify (h)); // { b: { c: 4 }, d: { e: { f: 1 } } }

h.d.e

54 ; console. log ( 'h.d.e set to 54.' ); // h.d.e set to 54.

console. log (JSON. stringify (g)); // { b: { c: 4 }, d: { e: 32 } }

console. log (JSON. stringify (a)); // { b: { c: 4 }, d: { e: 32 } }

console. log (JSON. stringify (h)); // { b: { c: 4 }, d: { e: 54 } }

} test ();

Slide 88

Slide 88

Array Methods: forEach

Slide 89

Slide 89

• The forEach() method executes a provided function once for each

array element.

Slide 90

Slide 90

var a

[ 'a' , 'b' , 'c' ]; a. forEach ( function ( element ) { console. log ( element ); }); // a // b // c

Slide 91

Slide 91

Array Methods: map

Slide 92

Slide 92

• The map() method creates a new array with the results of calling a provided function on every element in this array.

Slide 93

Slide 93

var numbers

[ 1 , 5 , 10 , 15 ]; var roots

numbers. map ( function ( x ) {

return x * 2 ; }); // roots is now [2, 10, 20, 30] // numbers is still [1, 5, 10, 15] var numbers

[ 1 , 4 , 9 ]; var roots

numbers. map (Math.sqrt); // roots is now [1, 2, 3] // numbers is still [1, 4, 9]

Slide 94

Slide 94

Array Methods: filter

Slide 95

Slide 95

• The filter() method creates a new array with all elements that pass the test implemented by the provided function.

Slide 96

Slide 96

var words

[ "spray" , "limit" , "elite" , "exuberant" , "destruction" , "present" ]; var longWords

words. filter ( function ( word ){

return word.length

6 ; });

// Filtered array longWords is ["exuberant", "destruction", "present"]

Slide 97

Slide 97

Array Methods: reduce

Slide 98

Slide 98

• The reduce() method applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value .

Slide 99

Slide 99

[ 0 , 1 , 2 , 3 , 4 ]. reduce ( (prev, curr) => prev + curr );

Slide 100

Slide 100

const pipe

(fns) => (x) => fns. reduce ((v, f) => f(v), x) const times2add1

pipe ([times2, add1]) times2add1 (5) // => 11

Slide 101

Slide 101

Import/Export

Slide 102

Slide 102

• The import statement is used to import functions, objects or primitives that have been exported from an external module, another script, etc.

Slide 103

Slide 103

// Import an entire module's contents. This inserts myModule into the current scope, containing all the exported bindings from the module identified by "my-module", often "my-module.js".

import

as myModule from

'my-module' ; // Import a single member of a module. This inserts myMember into the current scope. import {myMember} from

'my-module' ; // Import multiple members of a module. This inserts both foo and bar into the current scope. import {foo, bar} from

'my-module' ; // Import a member with a more convenient alias. This inserts shortName into the current scope. import {reallyReallyLongModuleMemberName as shortName}

from

'my-module' ; // Import an entire module for side effects only, without importing any bindings. import

'my-module' ; // Import multiple members of a module with convenient aliases. import { reallyReallyLongModuleMemberName as shortName, anotherLongModuleName as short } from

'my-module' ;

Slide 104

Slide 104

• The export statement is used to export functions, objects or primitives from a given file (or module).

Slide 105

Slide 105

// Named exports // exports a function declared earlier

export { myFunction };

// exports a constant export const foo = Math.sqrt(2); // Default exports (only one per script) export default function () {}

// or 'export default class {}' // there is no semi-colon here

Slide 106

Slide 106

Classes

Slide 107

Slide 107

• The class statement is simply a syntactic sugar for prototype inheritance.

• No new object-oriented class concept defined

Slide 108

Slide 108

// Basic class declaration

class

Vehicle {

constructor (type, wheels) {

this .type = type;

this .wheels = wheels; } } // The old way function

Vehicle (type, wheels) {

this .type = type;

this .wheels = wheels; }

Slide 109

Slide 109

• Prototype functions help to extend class methods • For class methods, no need to use function keyword

Slide 110

Slide 110

class

Vehicle {

constructor (type, wheels) {

this .type = type;

this .wheels = wheels; }

get

type (){

return

this .type: } }

Slide 111

Slide 111

Promises

Slide 112

Slide 112

• The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.

Slide 113

Slide 113

.then() .catch() Promise pending fulfill reject return return pending Promise error handling .then(onRejection) .catch(onRejection) .then(onFulfillment) async actions