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

JavaScript in Browsers

JavaScript in Browsers

Covers JavaScript in Browser Environment: HTML5, Browser Object Model, Document Object Model, AJAX: XmlHttpRequest and Fetch API (Promises), CORS

Jussi Pohjolainen

October 14, 2017
Tweet

More Decks by Jussi Pohjolainen

Other Decks in Technology

Transcript

  1. Single-page Applications (SPA) • Web app that fits on a

    single web page • Fluid UX, like desktop app • Examples like Gmail, Google maps • Html page contains mini-views (HTML Fragments) that can be loaded in the background • No reloading of the page, better UX • Requires handling of browser history, navigation and bookmarks
  2. JavaScript • SPAs are implemented using JavaScript and HTML •

    Usually we use some framework for this • ECMAScript is a scripting language, standardized by Ecma International • In Browsers, ECMAScript is commonly called JavaScript • JavaScript = Native (EcmaScript) + Host objects (browser)
  3. JavaScript • EcmaScript • String, Number, Operators, Statements, Math, Date,

    Array, Boolean, RegExp.. • Browser BOM • window, navigator, screen, history, location • HTML DOM • DOM document, element, attribute, events • JavaScript = EcmaScript + BOM + DOM
  4. Learning Path for Front-end Core EcmaScript Browser Host Objects JavaScript

    in Front-end HTML5 CSS Static Web-pages JavaScript Frameworks: React, AngularJS, ... Also basic understanding of HTTP and REST API...
  5. HTTP network protocol • HTTP is a network protocol of

    the Web • Hypertext Transfer Protocol • Delivers resources on the WWW • Usually delivered by TCP/IP • HTTP client sends a request to HTTP server • Default port is 80 • Resource can be a file or dynamically generated query result
  6. Structure of HTTP • Consists of request and response •

    Format • an initial line, • zero or more header lines, • a blank line, • optional message body (this is the resource) • Example <initial line, different for request and response> Header1: value1 Header2: value2 <optional message body>
  7. HTTP REQUEST: Initial Line • Initial line is different for

    the request than response. • Request line has three parts • method name, local path to resource, version of http • Example • GET /path/to/file/index.html HTTP/1.0 • Method name can be GET, POST, PUT, DELETE...
  8. HTTP RESPONSE: Initial Line • The initial response line, called

    the status line • Typical status lines • HTTP/1.0 200 OK • HTTP/1.0 404 Not Found • Status code (200, 404) is computer-readable, reason phrase is human-readable • Status codes • 1xx, information message • 2xx, success • 3xx, redirect • 4xx, client error • 5xx, server error • See all status codes • http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
  9. Header Lines • Header lines provide information about the request

    and response • Header-name: value • HTTP 1.0 provides 16 headers, HTTP 1.1 provides 46 headers • For example client should tell who is making the request • User-Agent: ... • Server should identify • Server: ...
  10. Message Body • Message body contains the resource • Usually

    the message body includes header lines • Content-type: • MIME type of the resource, for example text/html, image/gif • Content-length • bytes
  11. Example HTTP REQUEST and HTTP RESPONSE GET /tekstiedosto.txt HTTP/1.1 Host:

    localhost:8080 User-Agent: curl/7.49.1 Accept: text/json HTTP/1.1 200 OK Server: GlassFish Server Open Source Edition 4.1.1 X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.1.1 Java/Oracle Corporation/1.8) Content-Type: text/xml;charset=ISO-8859-1 Date: Tue, 10 Jan 2017 10:27:34 GMT Content-Length: 12 Hello World
  12. Example HTTP REQUEST and HTTP RESPONSE POST /MunSoftaniTestaus/MunHienoServlet HTTP/1.1 Host:

    localhost:8080 User-Agent: curl/7.49.1 Accept: */* Content-type: text/plain Content-Length: 9 Some data HTTP/1.1 200 OK Server: GlassFish Server Open Source Edition 4.1.1 X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.1.1 Java/Oracle Corporation/1.8) Content-Type: text/plain;charset=ISO-8859-1 Date: Tue, 10 Jan 2017 10:39:58 GMT Content-Length: 9 Some data
  13. Lab

  14. HTML5: It's really easy! <!DOCTYPE html> <html> <head> <title> Title

    </title> <meta charset="UTF-8" /> <style media="screen"></style> </head> <body> The content </body> </html>
  15. HTML5 vs XHTML5: MIME • HTML5 • text/html • XHTML5

    • application/xhtml+xml • See: • https://wiki.whatwg.org/wiki/HTML_vs._XHTML
  16. Simple Embedded JS <!DOCTYPE html> <html> <head> <title>Title</title> <meta charset="UTF-8"

    /> </head> <body> <script>console.log('hello world')</script> </body> </html> JS part of the Web page
  17. Simple External JS <!DOCTYPE html> <html> <head> <title>Title</title> <meta charset="UTF-8"

    /> </head> <body> <script src="myscript.js" /> </body> </html> Let's fetch the JS from external file
  18. Lab

  19. Browser Object Model • Browser specific convention to all the

    objects exposed by web browser • There is no standard implementation and no strict definition • Browser vendors are free to implement BOM • In Browsers, you use EcmaScript + Host Objects • Host Objects are • BOM (Browser object model) • DOM (Document object model) • DOM has strict definition from W3C / WHATWG
  20. chrome location document history navigator applicationCache screen ... window Some

    BOM objects in Chrome getElementsByTagName createTextNode appendChild removeChild ...
  21. Lab

  22. Intro to Events • Some interaction on html – page:

    • Mouse click (onclick) • Web page loading (onload) • Mousing over and out (onmouseover, onmouseout) • Submitting HTML form (onsubmit) • Key handling, web page completing, user scrolling or resizing …
  23. Evolution of Events • DOM Level 0 (Introduced in Netscape)

    • <a href="http://www.opera.com/" onclick="alert('Hello')">Say hello</a> • DOM Level 2 (W3C) • document.getElementById("my-link").addEventListener("click", myFunction, false); • Microsoft (IE) did not follow the W3C model until IE8. IE11 deletes its support for MS model
  24. Example Handler Properties • button.onfocus • button.onblur • button.ondblclick •

    button.onmouseover • button.onmouseout • window.onkeypress • window.onkeydown • window.onscroll
  25. Inline Event Handler <!DOCTYPE html> <html> <head> <title>Title</title> <script> function

    doIt() { console.log("Hello"); } </script> </head> <body> <button ondblclick="doIt()">Click</button> </body> </html>
  26. Inline Event Handler • Try to avoid inline event handlers

    they are considered bad practice • Avoid mixing html and js! • If you have "100 buttons", the maintanence of these can be hard
  27. Better Way <!DOCTYPE html> <html> <head> <title>Title</title> <script> function clicked()

    { console.log("click"); } function ready() { var b = document.querySelector("#mybutton"); b.ondblclick = clicked; } window.onload = ready; </script> </head> <body> <button id="mybutton">Click</button> </body> </html>
  28. Canceling Default Behaviour: return false <!DOCTYPE html> <html> <head> <title>Title</title>

    <script> function clicked(event) { console.log("click"); return false; } function ready() { var b = document.querySelector("#link"); b.onclick = clicked; } window.onload = ready; </script> </head> <body> <a id="link" href="http://mozilla.org">Click</a> </body> </html> Won't open mozilla.org
  29. <!DOCTYPE html> <html> <head> <title>Title</title> <script> function count() { var

    height = document.forms.myform.height.value; var weight = document.forms.myform.weight.value; document.forms.myform.result.value = (weight / (height*height)); } window.onload = () => { let button = document.querySelector('#button') button.onclick = count; } </script> </head> <body> <form name="myform"> Height (m):<br/> <input type="text" name="height"/><br/> Weight (kg):<br/> <input type="text" name="weight"/><br/> <input type="button" id="button" value="BMI"/><br/> BMI<br/> <input type="text" name="result"/> </form> </body> </html> Accessing Form by using DOM Level 0
  30. Lab

  31. W3C DOM • DOM – Document Object Model – cross-platform

    and language- independent convention for interacting with objects in HTML and in XML. • With DOM you can manipulate html/xml document! Dynamic html! • Public interface available: http://www.w3.org/DOM/DOMTR
  32. W3C DOM Levels (Legacy) • ( DOM Level 0 and

    Intermediate DOM ) • Not W3C Standards, used in Netscape 2 (Level 0) and Netscape 4 (Intermediate DOM) • DOM Level 1 • 1998: Ability to change entire HTML or XML document • Core and HTML specifications • Level of support: excellent • DOM Level 2 • 2001: Introduces “getElementById” function, event model and support for XML namespaces • Core, Views, Events, Style, Traversal and Range, HTML • Level of Support: good • DOM Level 3 • 2004: XPath, focus on keyboard event handling • Core, Load, Save, Validation, Events, XPath
  33. WHATWG: DOM Living Standard • WHATWG DOM "standardizes" DOM •

    DOM LEVEL 3 core and DOM LEVEL 3 Events • Selectors API Level 2 • And others • https://dom.spec.whatwg.org/
  34. DOM (Level 2) Event Handling • Methods for adding and

    removing events • addEventListener • removeEventListener • Multiple event handlers can be registered for the same event!
  35. <!DOCTYPE html> <html> <head> <title>Title</title> <script> window.addEventListener('load', ready); function ready()

    { let p = document.querySelector("#clickme"); p.addEventListener('click', doIt); } function doIt() { alert("Hello"); } </script> </head> <body> <p id="clickme">click</p> </body> </html>
  36. Remove function ready() { let p = document.querySelector("#clickme"); p.addEventListener('click', doIt);

    } function doIt() { alert("Hello"); let p = document.querySelector("#clickme"); p.removeEventListener('click', doIt); }
  37. Multiple Listeners function ready() { let p = document.querySelector("#clickme"); p.addEventListener('click',

    () => alert("Hello")); p.addEventListener('click', () => alert("World")); }
  38. Event Object <script> window.addEventListener('load', ready); function ready() { let p

    = document.querySelector("#clickme"); p.addEventListener('click', doIt); } function doIt(event) { alert("hello"); let p = event.target; p.removeEventListener('click', doIt); } </script> It's an event -object
  39. Event Object function ready() { let p = document.querySelector("#clickme"); p.addEventListener('click',

    doIt); } function doIt(event) { console.log(event.type); console.log(event.timeStamp); } See doc for all possibilities
  40. Lab

  41. stopPropagation: only p will trigger function ready() { let p

    = document.querySelector("#pClickme"); let div = document.querySelector("#divClickMe"); p.addEventListener('click', (e) => { e.stopPropagation(); alert("p");} ); div.addEventListener('click', (e) => alert("div")); }
  42. Script function ready() { let ul = document.querySelector("#list"); ul.addEventListener('click', (e)

    => { console.log(e.target); // <li>Hello</li> console.log(e.target.nodeName); // LI if(e.target.nodeName == "LI") { alert(e.target.id); // item-1 or item-2 } } ); }
  43. Lab

  44. DOM • Programming Interface for HTML and XML documents •

    You can change dynamically the document using DOM • The document is presented in nodes • Most browsers support both • W3C DOM • WHATWG DOM • And in addition have extensions to these • DOM is not a programming language, it's an specification
  45. WHATWG: DOM Living Standard • DOM For all structured Documents

    • WHATWG DOM "standardizes" DOM • DOM LEVEL 3 core and DOM LEVEL 3 Events • Selectors API Level 2 • And others • https://dom.spec.whatwg.org/ • For HTML also additions • https://html.spec.whatwg.org/multipage/dom.html • Other languages support also DOM, not just JavaScript
  46. document • document object represents the web page loaded •

    Is the entry point into web page's content (DOM Tree) • Some methods for getting elements • getElementsById(id) • getElementsByTagName(name) • querySelector(cssselector) • The DOM tree can be traversed in a lot of different ways • DOM Tree consists of nodes. Node can be for example • element, attribute, text ...
  47. <!DOCTYPE html> <html hello="world"> <head> <title>Title</title> </head> <body> <script> var

    htmlElementNode = document.documentElement; console.log(htmlElementNode instanceof Node); // true // Element extends Node console.log(htmlElementNode instanceof Element); // true console.log(htmlElementNode.getAttribute("hello")) // world </script> </body> </html>
  48. Node? • Node is a base "class" for • Element,

    Document, Text ... • For each Node you can use • childNodes() • firstChild() • lastChild() • nextSibling() • nodeType() • nodeValue • textContent()
  49. Node • In DOM, each object is Node • In

    this • <p>Hello</p> • You have two nodes 1) element node p 2) text node Hello • Text node is child node of p element. P element is parent node of the text node
  50. <!DOCTYPE html> <html><head><title>My Title</title></head> <body> <script> var htmlElementNode = document.documentElement;

    var headElementNode = htmlElementNode.firstChild; var titleElementNode = headElementNode.firstChild; var titleTextNode = titleElementNode.firstChild; var titleString = titleTextNode.nodeValue; console.log(titleString); </script> </body> </html>
  51. <!DOCTYPE html> <html hello="world"><head><title>My Title</title></head> <body> <script> var htmlElementNode =

    document.documentElement; var helloAttributeNode = htmlElementNode.getAttributeNode("hello"); var attributeText = helloAttributeNode.nodeValue console.log(attributeText); </script> </body> </html>
  52. Getting Elements More Easier • Getting list of elements •

    document.getElementsByTagName() • Getting with id • document.getElementById() • Getting use CSS selectors • document.querySelector()
  53. <!DOCTYPE html> <html> <head> <title>My Title</title> </head> <body> <h1>Title 1</h1>

    <h1>Title 2</h1> <script> var allH1Elements = document.getElementsByTagName("h1"); var firstH1 = allH1Elements[0]; firstH1.firstChild.nodeValue = "Hello!"; </script> </body> </html> Getting all elements with tag H1
  54. <!DOCTYPE html> <html> <head> <title>My Title</title> </head> <body> <h1 id="mytitle">Title

    1</h1> <h1>Title 2</h1> <script> var firstH1 = document.getElementById("mytitle"); firstH1.firstChild.nodeValue = "Hello!"; </script> </body> </html> Getting H1 with the id of mytitle
  55. <!DOCTYPE html> <html> <head> <title>My Title</title> </head> <body> <h1 id="mytitle">Title

    1</h1> <h1>Title 2</h1> <script> var firstH1 = document.querySelector("#mytitle"); firstH1.firstChild.nodeValue = "Hello!"; </script> </body> </html> Using CSS Query Selector for getting the H1
  56. Lab

  57. Whitespaces.... We have a problem! <!DOCTYPE html> <html> <head> <title>My

    Title</title> </head> <body> <div id="myDiv"> <h1>Title</h1> </div> <script> var div = document.querySelector("#myDiv"); var h1 = div.firstChild; var text = h1.firstChild; text.nodeValue = "Hello"; </script> </body> </html> We are NOT getting the H1 Here!
  58. <div id="myDiv"> <h1>Title</h1> </div> <script> var div = document.querySelector("#myDiv"); var

    whiteSpace = div.firstChild; var h1 = whiteSpace.nextSibling; var text = h1.firstChild; text.nodeValue = "Hello"; </script>
  59. firstChild vs firstElementChild <div id="myDiv"> <h1>Title</h1> </div> <script> var div

    = document.querySelector("#myDiv"); var h1 = div.firstElementChild; var text = h1.firstChild; text.nodeValue = "Hello"; </script> Bypassing the text node..
  60. textContent <div id="myDiv"> <h1>Title</h1> </div> <script> var div = document.querySelector("#myDiv");

    var h1 = div.firstElementChild; //var text = h1.firstChild; //text.nodeValue = "Hello"; h1.textContent = "Hello"; </script>
  61. textContent vs innerHTML <div id="myPre"> </div> <script> var div =

    document.querySelector("#myPre"); div.textContent = "<h1>Moi</h1>"; </script> In browser we are seeing also the < and > characters
  62. textContent vs innerHTML <div id="myPre"> </div> <script> var div =

    document.querySelector("#myPre"); div.innerHTML = "<h1>Moi</h1>"; </script> In innerHTML the <h1> and </h1> are presented as tags..
  63. Lab

  64. Creating and appending <script> function main(event) { let h1 =

    document.createElement("h1") let text = document.createTextNode("Hello World") h1.appendChild(text) document.getElementsByTagName("body")[0].appendChild(h1) } window.addEventListener('load', main) </script> Creating new elements and text nodes!
  65. Creating attribute function main(event) { let a = document.createElement("a") a.setAttribute("href",

    "http://www.tamk.fi") let text = document.createTextNode("tamk") a.appendChild(text) document.getElementsByTagName("body")[0].appendChild(a) } window.addEventListener('load', main)
  66. insertBefore <!DOCTYPE html> <html> <head> <title>My Title</title> <script> function main(event)

    { let a = document.createElement("a") a.setAttribute("href", "http://www.tamk.fi") let text = document.createTextNode("tamk") a.appendChild(text) let p = document.getElementById("someid") let parent = p.parentElement parent.insertBefore(a, p) } window.addEventListener('load', main) </script> </head> <body> <p id="someid">Hello</p> </body> </html> Insert the link (a) before the p under body
  67. removeChild <!DOCTYPE html> <html> <head> <title>My Title</title> <script> function main(event)

    { let body = document.getElementsByTagName('body')[0] let p = document.getElementById('someid') body.removeChild(p) } window.addEventListener('load', main) </script> </head> <body> <p id="someid">Hello</p> </body> </html>
  68. replaceChild <!DOCTYPE html> <html> <head> <title>My Title</title> <script> function main(event)

    { let body = document.getElementsByTagName('body')[0] let p = document.getElementById('someid') let h1 = document.createElement('h1') h1.appendChild(document.createTextNode('Hello World')) body.replaceChild(h1, p) } window.addEventListener('load', main) </script> </head> <body> <p id="someid">Hello</p> </body> </html>
  69. Lab

  70. AJAX • AJAX: Asynchronous JavaScript and XML • AJAX is

    about updating parts of web page without reloading the whole page • Essential part when creating Single Page Apps!
  71. Synchronous vs Asynchronous • Synchronous requests blocks the client (browser

    unresponsive) until request is done • Asynchronous requests does not block the client -> User can interact with the web page while at the same time the request is being fulfilled • Asynchronous requests usually work with callbacks or Promises • AJAX requests are asynchronous, also web workers and setTimeout
  72. XMLHttpRequest • Modern browsers support built-in XMLHttpRequest object • All

    about sending and receiving data from server. • Instantiate in normal fashion: • var xmlobj = new XMLHttpRequest();
  73. <!DOCTYPE html> <html> <head><title>My Title</title> <script> function buttonClicked(event) { var

    xmlobj = new XMLHttpRequest(); xmlobj.open("GET", // HTTP POST or GET? "./somefile.txt", // URL true); // async or not? xmlobj.send(); // Send it } window.addEventListener('load', (event) => { document.getElementById('myButton').addEventListener('click', buttonClicked) }) </script> </head> <body> <button id="myButton">Fetch</button> </body> </html>
  74. To quickly create Web Server (http) • Install Node.js •

    Install http-server module globally: • npm install http-server –g • Then start the http-server in your project folder: • http-server • Open browser • http://127.0.0.1:8080
  75. Asynchronous • When setting the async parameter to true, the

    server side script is run in background. • Javascript does not have to wait for the server response.. You can • Execute other scripts while waiting server response • Deal with the response when ready • Specify a function that is called when response is ready!
  76. onreadystatechange function buttonClicked(event) { var xmlobj = new XMLHttpRequest(); xmlobj.onreadystatechange

    = function() { console.log(xmlobj.readyState) } xmlobj.open("GET", "./somefile.txt", true); xmlobj.send(); }
  77. State of the Request • 0: Not initialized • 1:

    open() has been called • 2: send() has been called • 3: loading • 4: request finished and response Ready
  78. responseText function buttonClicked(event) { var xmlobj = new XMLHttpRequest(); xmlobj.open("GET",

    "./somefile.txt", true); xmlobj.onreadystatechange = function() { if(xmlobj.readyState == 4) { console.log(xmlobj.responseText) } } xmlobj.send(); }
  79. Status of the Request • Also HTTP Status is received

    • 200: “Ok” • 404: “Page not found” • … • if(xmlobj.status == 200 && xmlobj.readyState == 4) { .. }
  80. With status function buttonClicked(event) { var xmlobj = new XMLHttpRequest();

    xmlobj.open("GET", "./somefile.txt", true); xmlobj.onreadystatechange = function() { if(xmlobj.readyState == 4 && xmlobj.status == 200) { console.log(xmlobj.responseText) } } xmlobj.send(); }
  81. AJAX and DOM function buttonClicked(event) { var xmlobj = new

    XMLHttpRequest(); xmlobj.open("GET", "./somefile.txt", true); xmlobj.onreadystatechange = function() { if(xmlobj.readyState == 4 && xmlobj.status == 200) { document.getElementById('content').innerHTML = xmlobj.responseText } } xmlobj.send(); }
  82. Lab

  83. Server Response • XMLHttpRequest has two attributes for the response

    • DOMString responseText • Document responseXML
  84. function buttonClicked(event) { var xmlobj = new XMLHttpRequest(); xmlobj.open("GET", "./students.xml",

    true); xmlobj.onreadystatechange = function() { if(xmlobj.readyState == 4 && xmlobj.status == 200) { let doc = xmlobj.responseXML let students = doc.getElementsByTagName("student") let firststudent = students[0] let firststudentname = firststudent.textContent document.getElementById('content').innerHTML = firststudentname } } xmlobj.send(); }
  85. Parsing JSON function buttonClicked(event) { var xmlobj = new XMLHttpRequest();

    xmlobj.open("GET", "./students.json", true); xmlobj.onreadystatechange = function() { if(xmlobj.readyState == 4 && xmlobj.status == 200) { let text = xmlobj.responseText let jsonArray = JSON.parse(text) document.getElementById('content').innerHTML = jsonArray[0].name } } xmlobj.send(); }
  86. Lab

  87. function buttonClicked(event) { var xmlobj = new XMLHttpRequest(); xmlobj.open("GET", "http://www.thomas-bayer.com/sqlrest/CUSTOMER/0/",

    true); xmlobj.onreadystatechange = function() { if(xmlobj.readyState == 4 && xmlobj.status == 200) { let doc = xmlobj.responseXML let firstname = doc.getElementsByTagName("FIRSTNAME")[0].textContent document.getElementById('content').innerHTML = firstname } } xmlobj.send(); }
  88. Same-origin policy • For security reasons, by default, XMLHttpRequest following

    same- origin policy • Only http requests to its own domain! • So access from 127.0.0.1/index.html -> 127.0.0.1/students.xml is allowed • From 127.0.01/index.html -> someothersite.com/students.xml is NOT allowed!
  89. CORS • Cross – Origin Resource Sharing (CORS) mechanism gives

    cross- domain access controls • enables secure cross-domain data transfers • Works by adding new HTTP Headers
  90. Adding a new header: students.php <?php header('Content-Type: text/xml'); header('Access-Control-Allow-Origin: *');

    ?> <students> <student>Tina Smith</student> <student>Paul Power</student> </students>
  91. Try it again... it should work! function buttonClicked(event) { var

    xmlobj = new XMLHttpRequest(); xmlobj.open("GET", "http://koti.tamk.fi/~pohjus/cors/students.php", true); xmlobj.onreadystatechange = function() { if(xmlobj.readyState == 4 && xmlobj.status == 200) { let doc = xmlobj.responseXML let firstname = doc.getElementsByTagName("student")[0].textContent document.getElementById('content').innerHTML = firstname } } xmlobj.send(); }
  92. Lab

  93. Using POST var xmlobj = new XMLHttpRequest(); xmlobj.open("POST", // POST

    or GET? "somescript.php", // URL true); // async or not? // Specify the data you want to send via POST xmlobj.setRequestHeader("Content-type","application/x-www-form-urlencoded"); // Send data xmlobj.send("name=Kalle");
  94. About Promises • Fetch API is a new way of

    doing AJAX • Fetch API uses Promises • Promises an alternative to callbacks delivering result of an async computation • Promises are part of EcmaScript 2015 • Previously you could use them as additional library • https://promisesaplus.com/ 122
  95. Problems with callbacks • When async done, do another async

    method (chaining) -> using callbacks can be messy • What is async fails? If you have chained async methods and one of them fails? • It is not standard, everyone can have they own version of doing callbacks 124
  96. Using Promises function promiseFunction(resolve, reject) { // time consuming async

    stuff if(true) { resolve("OK!"); } else { reject("Failed!"); } } function onSuccess(msg) { console.log(msg); } function onError(msg) { console.log(msg); } let promise = new Promise(promiseFunction); promise.then(onSuccess, onError); promise.then(onSuccess).catch(onError); You can do both here 125
  97. Node.JS callbacks const fs = require('fs'); fs.readFile('mytest.json', function (error, text)

    { if (error) { console.error('Error while reading config file'); } else { try { const obj = JSON.parse(text); console.log(JSON.stringify(obj)); } catch (e) { console.error('Invalid JSON in file'); } } } ); File I/O module 126
  98. Node.JS promise const util = require('util'); const fs = require('fs');

    const promiseReadFile = util.promisify(fs.readFile); promiseReadFile('mytest.json') .then(function (text) { // const obj = JSON.parse(text); console.log(JSON.stringify(obj)); }) .catch(function (error) { // // File read error or JSON SyntaxError console.error('An error occurred', error); }); util.promisify is Node 8 feature 127
  99. Simple Example function doSomeTimeConsumingStuff() { function asyncOperation(resolve, reject) { setTimeout(()

    => resolve("Done"), 1000); } return new Promise(asyncOperation); } doSomeTimeConsumingStuff().then(result => console.log('Result: ' + result)); 128
  100. function promiseFunction(resolve, reject) { // time consuming async stuff if(true)

    { resolve(4); } else { reject("First promise failed!"); } } function onSuccess(result) { let p = new Promise((resolve, reject) => { // time consuming async stuff if(true) { resolve(result + 4); } else { reject("Second promise failed"); } } ); return p; } function onError(msg) { console.log(msg); } let promise = new Promise(promiseFunction); promise.then(onSuccess).then((result) => console.log("sum = " + result)).catch(onError); Returns promise Chaining with then Can handle both errors! 129
  101. Fetch API • Alternative (new) way of doing AJAX •

    Whatwg living standard • https://fetch.spec.whatwg.org/ • Uses promises
  102. <script> function doIt(event) { function responseIsReady(response) { return response.json() }

    function jsonIsParsed(studentsJsonArray) { document.getElementById('content').innerHTML = studentsJsonArray[0].name } // studens.json: [{"name": "Tina Smith"}, {"name": "Paul Power"}] fetch('./students.json').then(responseIsReady).then(jsonIsParsed) } window.addEventListener('load', (event) => { document.getElementById('myButton').addEventListener('click', doIt); }) </script>
  103. Error Handling fetch('http://..../customers').then(function(response) { var contentType = response.headers.get('content-type'); // status

    200 - 299 if(!response.ok) { throw new Error('Network response was not ok!'); } if(!contentType.includes('application/json')) { throw new Error('It was not json') } return response.json(); }).then(function(jsonObject) { // do something with the jsonObject }).catch(function(error) { console.log('There has been a problem with your fetch operation: ' + error.message); });
  104. POST var myHeaders = new Headers() myHeaders.append('Content-type', 'text/json') var init

    = { method: 'post', headers: myHeaders, body: {'name': 'jack'} } fetch('http://www.company.com/api/students', init).then(responseIsReady).then(jsonIsParsed)
  105. Lab

  106. FormData • FormData is a easy way of creating key/value

    pairs from a form • When having a form in HTML page you can just create the FormData by • let formData = new FormData(someFormDomElement) • Then by using Fetch API or XmlHttpRequest, it's really easy to send user given values to backend
  107. Example function doIt (event) { let formData = new FormData(document.getElementById('myForm'))

    var init = { method: 'post', body: formData } fetch('http://.../postdata.php', init).then(responseIsReady).then(jsonIsParsed) }
  108. Webpack • Bundles several JS – files into one •

    Supports ES 2015 modules • Install locally • npm install --save-dev webpack
  109. <!DOCTYPE html> <html> <head> <title>Title</title> <meta charset="UTF-8" /> <style media="screen"></style>

    <script src="dist/main.js"></script> </head> <body> The content </body> </html> Webpack will generate this for us!
  110. src/index.js import PlayerObject from './PlayerObject.js' var player = new PlayerObject(5,

    5) window.addEventListener('load', () => { document.querySelector('body').innerHTML = `<p>Player position x = ${player.x}, y = ${player.y}` }) ES2015 modules
  111. src/PlayerObject.js class PlayerObject { constructor (x, y) { this.x =

    x this.y = y } } export default PlayerObject
  112. Packaging all into one • By using one command you

    can package these file into one • node ./node_modules/webpack/bin/webpack.js src/index.js
  113. Canvas API • In HTML5 <canvas> element can be used

    to draw graphics via scripting in JavaScript • Draw graphics, bitmaps, create animations... • Really easy • <canvas></canvas> • And then in JS start to draw to the element
  114. Implementing a Game // What keys are down let keysDown

    = new Set() // For drawing let ctx let canvas // Game object let x = 50 let y = 50
  115. function init () { canvas = document.querySelector('canvas') ctx = canvas.getContext('2d')

    canvas.width = window.innerWidth canvas.height = window.innerHeight window.addEventListener('keydown', (event) => { keysDown.add(event.keyCode) }) window.addEventListener('keyup', (event) => { keysDown.clear(event.keyCode) }) window.requestAnimationFrame(gameloop); } window.addEventListener('load', (event) => { init() })
  116. function gameloop() { ctx.fillStyle = 'rgb(255, 255, 255, 1)' ctx.fillRect(0,

    0, canvas.width, canvas.height) ctx.fillStyle = 'rgb(0,0,0)' ctx.fillRect(x, y, 50, 50) moveObjects() window.requestAnimationFrame(gameloop); }
  117. function moveObjects() { const Direction = {UP: 87, DOWN: 83,

    LEFT: 65, RIGHT: 68} if (keysDown.has(Direction.UP)) { y-- } if (keysDown.has(Direction.DOWN)) { y++ } if (keysDown.has(Direction.LEFT)) { x-- } if (keysDown.has(Direction.RIGHT)) { x++ } }
  118. FileReader <p>File: <input id="files" type="file" accept=".java,.html"></p> <script> function read(e) {

    let text = e.target.result console.log(text) } function readFile(file) { var reader = new FileReader(); reader.onload = read reader.readAsText(file) } function handleFileSelect(evt) { let f = evt.target.files[0] readFile(f) } document.getElementById('files').addEventListener('change', handleFileSelect); </script>
  119. Others • Web Workers • For threading • Web Storage

    • Store data inside of browser • FileReader • To read files • Drag and Drop • Dragging and dropping elements