From d9fb04936a8583a7d2e07dc3b7705a56f430dca1 Mon Sep 17 00:00:00 2001 From: Nouran Mahmoud Date: Tue, 26 Nov 2019 01:21:08 +0100 Subject: [PATCH] Lesson planning for the js week1, week2 --- Week1/LESSONPLAN.md | 97 +++++++++++++ Week2/LESSONPLAN.md | 326 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 418 insertions(+), 5 deletions(-) diff --git a/Week1/LESSONPLAN.md b/Week1/LESSONPLAN.md index 1c5e1f403..77aad8cdf 100644 --- a/Week1/LESSONPLAN.md +++ b/Week1/LESSONPLAN.md @@ -16,23 +16,101 @@ FIRST HALF (12.00 - 13.30) Notes: +- APIs are created by providers and used by consumers (BE provider, FE consumer) +- Give real life example like (Devices like TV, any machine + electricity power socket interface which provides power to any external device) +- Communication between software and user needs UI interface but software and software needs API as an interface. - Part of an application that can be communicated with from an outside source - Connect to it using "endpoints" - Mostly used to request data from some service +- Software well-known APIs (Fb APIs, Twitter APIs, Maps APIs, weather APIs); +- API doesn't care which language or technology is used in the consumer or the provider + +### Types of APIs:- +- Private: for employees only under a company network for internal use. +- Semi-private: for clients who paid for the API. +- Public: for everyone on the web. + +### Architecture styles of API: +- Single purpose: API that gives a direct and specific service. +- Aggregated API: one API as a wrapper for multiple APIs. +- Web services API: punch of APIs working together to forma whole app. + +### Basic structure of REST API + +- Endpoint: https://api.example.com +- Endpoint with version: https://api.example.com/v1 +- Resources: +* https://api.example.com/v1/users +* https://api.example.com/v1/users/create +* https://api.example.com/v1/users/1 +* https://api.example.com/v1/users/1/edit +- Query params: +* https://api.example.com/v1/users?limit=10 + **Show examples** +Use [open weather app](https://openweathermap.org/api) +- Create an account or use the public key used in the examples. +- Use the endpoint for forecast and make a request via js file [Get current city weather by city name](https://openweathermap.org/current#name) +- Let them do the same using another endpoint [Get hourly forcasting by city name](https://openweathermap.org/api/hourly-forecast#name5) + 2. What is `AJAX` and how to apply it (`XMLHttpRequest`) Notes: +- Before AJAX all page reload for all requests, via refreshing the url in the address bar with the new resource. - It's a technique, not a technology - `AJAX` stands for Asynchronous JavaScript and XML - Nowadays we use `JSON` instead of `XML` - Fetch data without reloading the page +- The XMLHttpRequest API is defined in the browser (window.XMLHttpRequest) **Do exercise** + +Steps of doing the following example:- +** Install the live server plugin in VS (go to plugins -> live server -> install) +1. Create self-invoked function to wrap your code +2. Create an object instance of `XMLHttpRequest` +3. Call the `open` function to fill it with the Request URL and the request Method +4. Call the `send` function to make the request +5. Add event listener with a callback for the sucess event `load` + + +Example using the XMLHttpRequest + +``` +const oReq = new XMLHttpRequest(); +oReq.open('GET', `https://api.openweathermap.org/data/2.5/weather?q=${cityName}`); +oReq.send(); +oReq.addEventListener('load', function (event) { + const data = JSON.parse(this.response); + if (data.cod >= 400) { + // error + console.log(data.message); + } else { + //success + console.log(data.coord.lat); + } +}); + +// or another way of getting data +oReq.load = function (event) { + // use oReq.response or this.response + const data = JSON.parse(this.response); + if (data.cod >= 400) { + // error + console.log(data.message); + } else { + //success + console.log(data.coord.lat); + } +}; + +``` + + SECOND HALF (14.00 - 16.00) 3. How to use libraries (`axios`) @@ -45,3 +123,22 @@ Notes: - Read the documentation on how to use it **Do Exercise** + +Same example but using axios + +``` +axios + .get(`https://api.openweathermap.org/data/2.5/weather?q=${cityName}`) + .then(function (response) { + // handle success + console.log(response.data); + }).catch(function (error) { + // handle error + console.log(error); + }).finally(function () { + // always be executed + console.log('I am always here') + }); +``` + +> Note: Give example at the end with binding/showing these data in a DOM element like a
or a list instead of only showing them on the console using console.log. \ No newline at end of file diff --git a/Week2/LESSONPLAN.md b/Week2/LESSONPLAN.md index 4e0d19aaa..5b814450b 100644 --- a/Week2/LESSONPLAN.md +++ b/Week2/LESSONPLAN.md @@ -12,7 +12,7 @@ The purpose of this class is to introduce to the student: FIRST HALF (12.00 - 13.30) -1. The structure and use of `Promises` +### 1. The structure and use of `Promises` Notes: @@ -22,21 +22,337 @@ Notes: **Show examples** -2. How to use the `fetch` API to do AJAX calls +- First give example about how to create a promise + +``` +let promiseToDoHomeWork = new Promise(function (resolve, reject) { + let isDone = true; + + if (isDone) { + resolve('homework is done!'); + } else { + reject('not done!'); + } +}); + +promiseToDoHomeWork + .then(function () { console.log('home work is done now'); }) + .catch(function () { console.log('home work has something wrong, can\'t be done'); }) + +``` + +- Nested promises example + +``` + +let attendClass = function () { + return new Promise(function (resolve, reject) { + resolve('I attend the class'); + }); +} + +let doTheHomeWork = function (message) { + return new Promise(function (resolve, reject) { + resolve(message + 'then I did the homework'); + }); +} + +let submitHomework = function (message) { + return new Promise(function (resolve, reject) { + resolve(message + 'so I submit my homework'); + }); +} + +attendClass() + .then(function (result) { + return doTheHomeWork(result); + }) + .then(function () { + return submitHomework(result); + }).catch(function (error) { + console.log(error); + }); + +``` + + +- Promise.all + +``` +Promise.all([attendClass(), doTheHomeWork(), submitHomework()]).then(function ([res1, res2, res3]) { console.log('all finished') }); +``` + +- Promise.race + +``` +Promise.race([attendClass(), doTheHomeWork(), submitHomework()]).then(function (result) { console.log('one of them finished') }); +``` + +- Example for converting XHR to promise as a preparation for `fetch` + +``` +function fetchResource(url) { + return new Promise(function (resolve, reject) { + const oReq = new XMLHttpRequest(); + oReq.open('GET', url); + oReq.send(); + oReq.addEventListener('load', function (event) { + const data = JSON.parse(this.response); + if (data.cod >= 400) { + // error + console.log('error', data); + reject(data); + } else { + //success + console.log('success', data); + resolve(data); + } + }); + }); +} + +fetchResource(`https://api.openweathermap.org/data/2.5/weather?q=amsterdam&appid=316f8218c0899311cc029a305f39575e`).then(function (result) { + console.log(result); +}); + +``` + +### 2. How to use the `fetch` API to do AJAX calls Notes: - Modern replacement of XMLHttpRequest - Uses Promise structure -- The Fetch API is defined in the browser +- The Fetch API is defined in the browser (window.fetch) - Only modern browsers support it (show [caniuse.com](https://caniuse.com/#feat=fetch)) +- Fetch API documentations by mozilla [link](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) **Do exercise** +``` +fetch('https://seriousnews.com/api/headlines') + .then(function (response) { + response.json(); + }).then(headlines => { + console.log(headlines) + }).catch(error => console.log(error)); +``` + SECOND HALF (14.00 - 16.00) -3. The `this` keyword and its relationship with `scope` +### 3. The `this` keyword and its relationship with `scope` + +Notes:- + +- The environment(or scope) in which the line is being executed is know as “Execution Context” +- The object that `this` refers to, changes every time execution context is changed. +- Whatever is calling the function passes the `this` value to it by default. +- We can pass specific `this` by `.bind`, `.call` or `.apply` + + +#### “this” refers to global object +``` +// Immediately Invoked Function Expression (IIFE) +(function () { + // First Example + function foo() { + console.log("Simple function call"); + console.log(this === window); + } + +foo(); //prints true on console +console.log(this === window) //Prints true on console. + +})(); +``` + +As you see in the example, the `foo()` function is called based on `window`, this makes the default `this` inside this `foo` function get the value `window` + +> Note: we say a function is called based on window when there's no object calling it, like `obj.foo()`, but calling `foo()` acts if it was `window.foo()` + +> Note: If `strict mode` is enabled for any function then the value of “this” will be “undefined” as in strict mode, global object refers to undefined in place of windows object. + +``` +function foo() { + 'use strict'; + console.log("Simple function call") + console.log(this === window); +} + +foo(); //prints false on console as in “strict mode” value of “this” in global execution context is undefined. +``` + +#### this refers to new instance (constructors) + +``` +function Person(fn, ln) { + this.first_name = fn; + this.last_name = ln; + + this.displayName = function () { + console.log(`Name: ${this.first_name} ${this.last_name}`); + } +} + +let person = new Person("John", "Reed"); +person.displayName(); // Prints Name: John Reed +let person2 = new Person("Paul", "Adams"); +person2.displayName(); // Prints Name: Paul Adams +``` + +- In Javascript, property of an object can be a method or a simple value. +- When an Object’s method is invoked then “this” refers to the object which contains the method being invoked. + +``` + +function foo() { + 'use strict'; + console.log("Simple function call") + console.log(this === window); +} + +let user = { + count: 10, + foo: foo, + foo1: function () { + console.log(this === window); + } +} + +user.foo() // Prints false because now “this” refers to user object instead of global object. +let fun1 = user.foo1; +fun1() // Prints true as this method is invoked as a simple function. +user.foo1() // Prints false on console as foo1 is invoked as a object’s method +``` + +> Note: the value of “this” depends on how a method is being invoked as well. + +#### “this” with call, apply methods +- These methods can be used to set custom value of `this` to the execution context of function, also they can pass arguments/parameters to the function + +``` +function Person(fn, ln) { + this.first_name = fn; + this.last_name = ln; + + this.displayName = function (prefix) { + console.log(`Name: ${prefix} ${this.first_name} ${this.last_name}`); + } +} + +let person = new Person("John", "Reed"); +person.displayName(); // Prints Name: John Reed +let person2 = new Person("Paul", "Adams"); +person2.displayName(); // Prints Name: Paul Adams + +person.displayName.call(person2, 'Mr'); // Here we are setting value of this to be person2 object +person.displayName.call(person2, ['Mr']); // Here we are setting value of this to be person2 object + +``` + +#### “this” with bind method +`bind` only create a copy of the function with the binded `this` inside without calling the function. +``` +function Person(fn, ln) { + this.first_name = fn; + this.last_name = ln; + + this.displayName = function () { + console.log(`Name: ${this.first_name} ${this.last_name}`); + } +} + +let person = new Person("John", "Reed"); +person.displayName(); // Prints Name: John Reed +let person2 = new Person("Paul", "Adams"); +person2.displayName(); // Prints Name: Paul Adams + +let person2Display = person.displayName.bind(person2); // Creates new function with value of “this” equals to person2 object +person2Display(); // Prints Name: Paul Adams +``` + +### 4. Arrow functions and JS versions Notes: +- JS versions https://www.w3schools.com/js/js_versions.asp +- Arrow functions can’t be used as constructors as other functions can. +- If you attempt to use new with an arrow function, it will throw an error. +- To create class-like objects in JavaScript, you should use the new ES6 classes instead +- Arrow func exmaples + +``` +// ES5 +var multiplyES5 = function (x, y) { + return x * y; +}; + +// ES6 +const multiplyES6 = (x, y) => { return x * y }; +``` + +The this keyword works differently in arrow functions. + +- The `this` value inside the arrow function gets binded and calcuated and assigned based on its wrapper/container/parent `this` value. +- The methods call(), apply(), and bind() will not change the value of this in arrow functions + +#### “this” with fat arrow function +``` +function Person(fn, ln) { + this.first_name = fn; + this.last_name = ln; + + this.displayName = () => { + console.log(this === window); + console.log(`Name: ${this.first_name} ${this.last_name}`); + } +} + +let person1 = new Person('Nouran', 'Mhmoud'); +person1.displayName(); // this doesn't equal window, because it gets `this` that is inside Person() constructor function. +``` + +In the following example, the foo1() gets the `window` as `this` value, because on interpretation time, the interpreter assign the `this` immediately based on the surrounding execution context which is `window` in the case of simple literal object. + +``` +let user = { + count: 10, + foo1: () => { + console.log(this === window); + } +} + +let user1 = user.foo1() // this equals window +``` + +## test your knowledge + +In this example, let the students guess the result and then go line by line as if you were an interpreter and execute the code. Or use the debugger tools on devtools to execute line by line. + +``` +function multiply(p, q, callback) { + callback(p * q); +} + +let user = { + a: 2, + b: 3, + findMultiply: function () { + multiply(this.a, this.b, function (total) { + console.log(total); + console.log(this === window); + }) + } +} + +user.findMultiply(); +//Prints 6 +//Prints true +``` + +## Wrapping up -- \ No newline at end of file +### `this` rules +- By default, “this” refers to global object which is `global` in case of NodeJS and `window` object in case of browser +- When a method is called as a property of object, then `this` refers to the parent object +- When a function is called with `new` operator then `this` refers to the newly created instance. +- When a function is called using `call` and `apply` functions then `this` refers to the value passed as first argument of call or apply method.