├── images
├── protochain.png
├── cantransition.png
├── domscreenshot.png
└── diagramforproto.png
├── README.md
├── LICENSE
├── advanced theory
├── authentication.md
├── APIs in JS.md
├── ES2016 and 2017.md
├── advanced array methods.md
├── AJAX.md
├── css3.md
├── testing.md
├── asynchronous JS.md
└── OOP with JS.md
└── basic theory
├── js and html.md
└── basic JS info.md
/images/protochain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/V1raNi/webdev-bootcamp-theory/HEAD/images/protochain.png
--------------------------------------------------------------------------------
/images/cantransition.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/V1raNi/webdev-bootcamp-theory/HEAD/images/cantransition.png
--------------------------------------------------------------------------------
/images/domscreenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/V1raNi/webdev-bootcamp-theory/HEAD/images/domscreenshot.png
--------------------------------------------------------------------------------
/images/diagramforproto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/V1raNi/webdev-bootcamp-theory/HEAD/images/diagramforproto.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # The Web Developer Bootcamp Theory
2 |
3 | This repository contains my notes which were taken during https://www.udemy.com/the-web-developer-bootcamp and https://www.udemy.com/the-advanced-web-developer-bootcamp
4 |
5 | The notes contain some basic and (a little) advanced information about JavaScript, CSS, React and Redux along with my comments. I tried to write everything in the way a novice learner (such as myself) would understand.
6 |
7 | Please bear in mind that the notes here do not cover everything, are not 100% complete, and are written based on the information from Udemy courses. So if you need something more comprehensive, please see other documentation online (MDN, W3, etc).
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Dmitry Shamshurin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/advanced theory/authentication.md:
--------------------------------------------------------------------------------
1 | # Authentication
2 |
3 | #### Table of Contents
4 |
5 | - [Authentication](#authentication)
6 | - [Table of Contents](#table-of-contents)
7 | - [One Way Hashing](#one-way-hashing)
8 | - [Example of Hashing](#example-of-hashing)
9 | - [Sign In (Authentication)](#sign-in-authentication)
10 | - [JWT (JSON Web Token)](#jwt-json-web-token)
11 | - [Authentication](#authentication-1)
12 | - [Sending JWT to Server](#sending-jwt-to-server)
13 |
14 | ## One Way Hashing
15 |
16 | It's converting data into a fixed length has string; we can only recreate the hash if we know the original data
17 |
18 | Once we have the has, we can't go back and figure out what the original data was
19 |
20 | It's applicable for saving passwords on our server - we never save actual password; the data that the site saves should be just hash and nothing else
21 |
22 | #### Example of Hashing
23 |
24 | Password 'password' -> given to a hash library 'bcrypt' -> $2a$10$9Mconplm8A780pY6iB2q.eBwkdldFbnz2tSH2uqHEi5B9KTpR3O8.
25 |
26 | ### Sign In (Authentication)
27 |
28 | Once we've saved that password as a has, the process of signing is like this:
29 |
30 | $2a$10$9Mconplm8A780pY6iB2q.eBwkdldFbnz2tSH2uqHEi5B9KTpR3O8. (in database) -> user provides a password ('password') -> password goes through 'bcrypt' -> hash is generated again -> compare those hashes -> log in
31 |
32 | ### JWT (JSON Web Token)
33 |
34 | jwt.io
35 |
36 | Users don't want to enter their passwords on every page; we need some proof that we have logged in in the past
37 |
38 | We can use JWTs as proof that we've logged in before - JWT is a web standard for storing signed data (sometimes called 'jot')
39 |
40 | JWT Format:
41 |
42 | ```
43 | Header: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
44 | Payload: eyJ1c2VySWQiOiIxMjM0In0.
45 | Signature: kud-czcx6yOSSQgB0lKbibHNFmlAJwrV8iRQ1Ha-r-Q
46 | ```
47 |
48 | Signature is used to make sure that the header and the payload has not been tempered with; both the header and the payload, and then also a secret key are inputs to generate the signature
49 | - A secret key is a string that we store on the server but we don't give people access to it (use env variables, install dotenv for connecting to .env file)
50 |
51 | The server is the one that keeps track of that secret key, and only it can know about the secret
52 | - If a hacker were to get access to that key then the hacker could also make fake JWTs with whatever header and payload that they want
53 | - So the thing that keeps this secure is the fact that this signature generation can only be done by the server, it can't be done by the client of by anyone else
54 |
55 | #### Authentication
56 |
57 | The server verifies the payload and the header to make sure it hasn't been tempered with, and if it hasn't, it looks in the payload to see that it has something like a user ID stored, and then if that user ID is there, that verifies that we've logged in in the past
58 |
59 | When the user signs in, we give the generated JWT back to the client; every authenticated request after that the client needs to send us the JWT back (if we're the server)
60 | - As long as the client sends a JWT for which that signature matches the signature that we generate on the server, we are authenticated
61 | - Once we look in this payload, we can see what the user ID is to figure out which user is authenticated
62 | - If something is changed (header, payload, signature) it will lead to an invalid signature problem
63 | - If the header or payload are different, since they are inputs to generate signature, it will result in the server trying to generate a different signature
64 |
65 | #### Sending JWT to Server
66 |
67 | The standard way to send the JWT is to include the JWT in the authorization header, and the first part of this header is typically 'Bearer' (type portion of authorization)
68 |
69 | HTTP Header: Authorization: Bearer \ (e.g. Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjM0In0.kud-czcx6yOSSQgB0lKbibHNFmlAJwrV8iRQ1Ha-r-Q)
--------------------------------------------------------------------------------
/advanced theory/APIs in JS.md:
--------------------------------------------------------------------------------
1 | # JSON API with JS
2 |
3 | This section mostly requires information which is in JS backend doc
4 |
5 | The main difference is that we don't load new pages, we are sending and receiving requests with data
6 |
7 | #### Table of Contents
8 |
9 | - [JSON API with JS](#json-api-with-js)
10 | - [Table of Contents](#table-of-contents)
11 | - [Endpoints](#endpoints)
12 | - [Responding with JSON](#responding-with-json)
13 | - [Routes](#routes)
14 | - [Index](#index)
15 | - [Create](#create)
16 | - [Show](#show)
17 | - [Update](#update)
18 | - [Delete](#delete)
19 | - [Helpers](#helpers)
20 | - [Serving a Static File](#serving-a-static-file)
21 |
22 | ## Endpoints
23 |
24 | Endpoints are basically routes
25 |
26 | Example with a todo app (RESTful):
27 |
28 | ```
29 | Verb Route Description
30 | GET /api/todos List all todos
31 | POST /api/todos Create a new todo
32 | GET /api/todos/:todoId Retrieve a todo
33 | PUT /api/todos/:todoId Update a todo
34 | DELETE /api/todos/:todoId Delete a todo
35 | ```
36 |
37 | ## Responding with JSON
38 |
39 | res.send is dynamic, depending on the contents of what we send: if we pass string, it will render html, but if we pass JS object, it will be treated as JSON
40 |
41 | ```javascript
42 | app.get('/', function(req, res) {
43 | res.send({message: 'Hi there from JS object'}); // it will convert to a string, and send as JSON
44 | // if we pass a string, it will be treated as a string
45 | res.send('{data: 12345}');
46 | });
47 | ```
48 |
49 | Also there is res.json method which does the same thing because in res.send source code it actually calls res.json (send is sort of parent)
50 |
51 | ```javascript
52 | app.get('/', function(req, res) {
53 | res.json({message: 'Hi there from JS object'});
54 | res.json('{data: 12345}'); // it will treat this string as a JSON
55 | });
56 | ```
57 |
58 | ## Routes
59 |
60 | We are assuming that we have this in our index.js file:
61 |
62 | ```javascript
63 | var todoRoutes = require('./routes/todos');
64 | app.use('/api/todos', todoRoutes);
65 | ```
66 |
67 | Schema for examples:
68 |
69 | ```javascript
70 | var mongoose = require('mongoose');
71 |
72 | var todoSchema = new mongoose.Schema({
73 | name: {
74 | type: String,
75 | required: 'Name cannot be blank!'
76 | },
77 | completed: {
78 | type: Boolean,
79 | default: false
80 | },
81 | created_date: {
82 | type: Date,
83 | default: Date.now
84 | }
85 | });
86 |
87 | var Todo = mongoose.model('Todo', todoSchema);
88 |
89 | module.exports = Todo;
90 | ```
91 |
92 | ### Index
93 |
94 | ```javascript
95 | // index route
96 | router.get('/', function(req, res) {
97 | db.Todo.find()
98 | .then(function(todos) {
99 | res.json(todos);
100 | })
101 | .catch(function(err) {
102 | res.send(err);
103 | });
104 | });
105 | ```
106 |
107 | ### Create
108 |
109 | ```javascript
110 | // create route
111 | router.post('/', function(req, res) {
112 | db.Todo.create(req.body)
113 | .then(function(newTodo) {
114 | // standard way to respond is res.send it back since it's importand to know that it worked, and date, the status abd the ID are going to be generated by mongo, so we want those to come back
115 | // we're also sending a different status code to be more explicit (201 - created)
116 | res.status(201).json(newTodo);
117 | })
118 | .catch(function(err) {
119 | res.send(err);
120 | })
121 | });
122 |
123 | // if we try to send along some other data (like mood which is not in our schema), it doesn't actually try and insert that because that's not a part of our schema, so mongo doesn't care about that (our only defined key is name in this example)
124 | ```
125 |
126 | ### Show
127 |
128 | ```javascript
129 | router.get('/:todoId', function(req, res) {
130 | db.Todo.findById(req.params.todoId)
131 | .then(function(foundTodo) {
132 | res.json(foundTodo);
133 | })
134 | .catch(function(err) {
135 | res.send(err);
136 | })
137 | });
138 | ```
139 |
140 | ## Update
141 |
142 | ```javascript
143 | router.put('/:todoId', function(req, res) {
144 | db.Todo.findOneAndUpdate({_id: req.params.todoId}, req.body, {new: true})
145 | .then(function(todo) {
146 | res.json(todo); // by default it responds with old data, before it was updated that's why we need {new: true}
147 | })
148 | .catch(function(err) {
149 | res.send(err);
150 | })
151 | });
152 |
153 | module.exports = router;
154 | ```
155 |
156 | ## Delete
157 |
158 | ```javascript
159 | router.delete('/:todoId', function(req, res) {
160 | db.Todo.remove({_id: req.params.todoId})
161 | .then(function() {
162 | res.json({message: 'We deleted it'});
163 | })
164 | .catch(function(err) {
165 | res.send(err);
166 | });
167 | });
168 | ```
169 |
170 | ## Helpers
171 |
172 | We can refactor routes file by moving all the logic inside our route handlers into a separate helper so that our routes will be really simple
173 | - Look up controllers in MVC framework
174 | - Are helper files the same as Controller files in the MVC framework?
175 | - I’d consider the handlers/routesto be more controllers
176 | - MAYBE not true: controller is mainly for processing logic and bringing together database and templates whereas helper is mainly used for shared codes like dates
177 | - Helpers are either in a helpers folder (helpers/todos.js) or named (todos_helper.js)
178 |
179 | Exports
180 | - Exports isn't exactly an alias for module.exports. exports.a = function b(){} means that module.exports.a is a function, but setting module.exports = function b(){} can not be done with just exports. If you want to do a "default" export and only export out a single thing, you have to use module.exports
181 |
182 | Routes file:
183 |
184 | ```javascript
185 | var express = require('express'),
186 | router = express.Router(),
187 | helpers = require('../helpers/todos');
188 |
189 |
190 | // index and post routes
191 | router.route('/')
192 | .get(helpers.getTodos)
193 | .post(helpers.createTodo);
194 |
195 | // show, update, and delete
196 | router.route('/:todoId')
197 | .get(helpers.getTodo)
198 | .put(helpers.updateTodo)
199 | .delete(helpers.deleteTodo);
200 |
201 | module.exports = router;
202 | ```
203 |
204 | Helpers file:
205 |
206 | ```javascript
207 | var db = require('../models');
208 |
209 | // exports object is initialized by node
210 |
211 | exports.getTodos = function(req, res) {
212 | db.Todo.find()
213 | .then(function(todos) {
214 | res.json(todos);
215 | })
216 | .catch(function(err) {
217 | res.send(err);
218 | });
219 | }
220 |
221 | exports.createTodo = function(req, res) {
222 | console.log(req.body);
223 | db.Todo.create(req.body)
224 | .then(function(newTodo) {
225 |
226 | res.status(201).json(newTodo);
227 | })
228 | .catch(function(err) {
229 | res.send(err);
230 | })
231 | }
232 |
233 | exports.getTodo = function(req, res) {
234 | db.Todo.findById(req.params.todoId)
235 | .then(function(foundTodo) {
236 | res.json(foundTodo);
237 | })
238 | .catch(function(err) {
239 | res.send(err);
240 | })
241 | }
242 |
243 | exports.updateTodo = function(req, res) {
244 | db.Todo.findOneAndUpdate({_id: req.params.todoId}, req.body, {new: true})
245 | .then(function(todo) {
246 | res.json(todo); // by default it responds with old data, before it was updated that's why we need {new: true}
247 | })
248 | .catch(function(err) {
249 | res.send(err);
250 | })
251 | }
252 |
253 | exports.deleteTodo = function(req, res) {
254 | db.Todo.remove({_id: req.params.todoId})
255 | .then(function() {
256 | res.json({message: 'We deleted it'});
257 | })
258 | .catch(function(err) {
259 | res.send(err);
260 | });
261 | }
262 |
263 | module.exports = exports;
264 | ```
265 |
266 | ## Serving a Static File
267 |
268 | We can serve static files with res.sendFile
269 |
270 | ```javascript
271 | app.use(express.static(__dirname + '/public'));
272 | app.use(express.static(__dirname + '/views'));
273 |
274 | app.get('/', function(req, res) {
275 | res.sendFile('index.html');
276 | });
277 | ```
--------------------------------------------------------------------------------
/advanced theory/ES2016 and 2017.md:
--------------------------------------------------------------------------------
1 | # ES 2016 and 2017
2 |
3 | #### Table of Contents
4 |
5 | - [ES 2016 and 2017](#es-2016-and-2017)
6 | - [Table of Contents](#table-of-contents)
7 | - [ES 2016](#es-2016)
8 | - [Exponentiation Operator](#exponentiation-operator)
9 | - [includes](#includes)
10 | - [ES 2017](#es-2017)
11 | - [padStart](#padstart)
12 | - [padEnd](#padend)
13 | - [Async Functions](#async-functions)
14 | - [Await](#await)
15 | - [Object async](#object-async)
16 | - [Class async](#class-async)
17 | - [Error Handling](#error-handling)
18 | - [HTTP Requests with async](#http-requests-with-async)
19 | - [await with Promise.all](#await-with-promiseall)
20 | - [Object Rest and Spread](#object-rest-and-spread)
21 | - [Object Rest](#object-rest)
22 | - [Object Spread](#object-spread)
23 |
24 | ## ES 2016
25 |
26 | ### Exponentiation Operator
27 |
28 | There exists a parameter to figure out value of one number to the power of another
29 |
30 | ```javascript
31 | // ES2015
32 | var calculatedNumber = Math.pow(2, 4);
33 |
34 | caltulatedNumber; // 16
35 |
36 | // ES2016
37 | var calculatedNumber = 2 ** 4;
38 |
39 | calculatedNumber; // 16
40 |
41 | // ES2015
42 | var nums = [1, 2, 3, 4];
43 | var total = 2;
44 |
45 | for (let i = 0; i < nums.length; i++) {
46 | total Math.pow(total, nums[i]);
47 | }
48 |
49 | // ES2016
50 | var nums = [1, 2, 3, 4];
51 | var total = 2;
52 |
53 | for (let i = 0; i < nums.length; i++) {
54 | total total **= nums[i];
55 | }
56 | ```
57 |
58 | ### includes
59 |
60 | In ES2015 we saw that strings have .includes which returns true if the value passed to it is included in the string
61 |
62 | In ES2016 arrays now have .includes as well, which is a good replacement for using indexOf to check if the value exists inside of an array
63 |
64 | ```javascript
65 | // ES2015
66 | var nums = [1, 2, 3, 4, 5];
67 | nums.indexOf(3) > -1; // true
68 | nums.indexOf(44) > -1; // false
69 |
70 | // ES2016
71 | var nums = [1, 2, 3, 4, 5];
72 | nums.includes(3); // true
73 | nums.includes(44); // false
74 | ```
75 |
76 | ## ES 2017
77 |
78 | ### padStart
79 |
80 | Allows us to pad (to place) a certain character number of times before the start of a string
81 | - The first parameter is the totale length of the new string
82 | - The second parameter is what to pad with from the start; the default is an empty space
83 |
84 | This is useful when we need to have strings that are all the same length but our input might now always have that. so maybe we want to pad some input with zeros or some other operator
85 |
86 | ```javascript
87 | 'awesome'.padStart(10); // ' awesome'
88 | 'awesome'.padStart(10, '!'); // '!!!awesome'
89 | ```
90 |
91 | ### padEnd
92 |
93 | The same as padStart, but places characters to the end of a string
94 |
95 | ```javascript
96 | 'awesome'.padEnd(10, '!'); // 'awesome!!!'
97 | ```
98 |
99 | ### Async Functions
100 |
101 | A special kind of function that is created using the word 'async'
102 |
103 | The purpose of async functions is to simplify writing asynchronous code, specifically Promises
104 |
105 | When the async function is invoked, a promise is returned to us and will resolve with whatever value is returned from the function
106 |
107 | ```javascript
108 | async function first() {
109 | return 'We did it!';
110 | }
111 |
112 | first(); // returns a promise
113 | first().then(val => console.log(val)); // 'We did it!'
114 | ```
115 |
116 | What makes them really special is the 'await' keyword
117 |
118 | #### Await
119 |
120 | A reserved keyword that can only be used inside of async functions
121 |
122 | Await pauses the execution of the async function and is followed by a Promise; the 'await' keyword waits for the promise to resolve, and then resumes the async function's execution and returnes the resolved value (like a pause button)
123 |
124 | Await allows us to write async code that reads like it's sync (we can remove the hassle of nested callbacks, promise chains or multiple yield statements and generator functions)
125 |
126 | ```javascript
127 | async function getMovieData() {
128 | console.log('starting!');
129 | var movieData = await $.getJSON('https://omdbapi.com?t=titanic&apikey=thewdb');
130 | // this line does NOT run until the promise (await) is resolved!
131 | console.log('all done!');
132 | console.log(movieData);
133 | }
134 |
135 | getMovieData(); // logs an object with data about the movie
136 | // we don't need .then or callback, or yield
137 | ```
138 |
139 | #### Object async
140 |
141 | We can also place async functions as methods inside objects by prefixing the method with the word async and using ES 2015 object method notation to write the function
142 |
143 | ```javascript
144 | var movieCollector = {
145 | data: 'titanic',
146 | async getMovie() {
147 | var response = await $.getJSON(`https://omdbapi.com?t=${this.data}&apikey=thewdb`);
148 | console.log(response);
149 | }
150 | }
151 |
152 | movieCollector.getMovie();
153 | ```
154 |
155 | #### Class async
156 |
157 | We can also place async functions as instance methods with ES2015 class syntax
158 |
159 | ```javascript
160 | class MovieData {
161 | constructor(name) {
162 | this.name = name;
163 | }
164 | async getMovie() {
165 | var response = await $.getJSON(`https://omdbapi.com?t=${this.name}&apikey=thewdb`);
166 | console.log(response);
167 | }
168 | }
169 |
170 | var m = new MovieData('shrek');
171 | m.getMovie();
172 | ```
173 |
174 | This seems great, but we're making a dangerous assumption - that our promises will be resolved successfully
175 |
176 | #### Error Handling
177 |
178 | If a promise is rejected using await, JS will throw an error, so we can easily use a try/catch statement inside of the try block to handle errors
179 |
180 | ```javascript
181 | async function getUser(user) {
182 | try {
183 | var response = await $.getJSON(`https://api.github.com/users/${user}`);
184 | console.log(response.name);
185 | } catch(e) {
186 | console.log('User does not exist!');
187 | }
188 | }
189 |
190 | getUser('elie'); // Elie Schoppik
191 | getUser('asdasdasd'); // User does not exist!
192 | ```
193 |
194 | #### HTTP Requests with async
195 |
196 | ```javascript
197 | // two requests are made sequentially, not parallelly
198 | async function getMovieData() {
199 | var responseOne = await $.getJSON('https://omdbapi.com?t=titanic&apikey=thewdb');
200 | // this response two will not begin until the entire responseOne is resolved
201 | // imagine if it takes several seconds, our app would slow down
202 | var responseTwo = await $.getJSON('https://omdbapi.com?t=shrek&apikey=thewdb');
203 | console.log(responseOne);
204 | console.log(responseTwo);
205 | }
206 |
207 | getMovieData();
208 | ```
209 |
210 | We can avoid this by returning the promises right away and make HTTP requests in parallel, and then 'await' their resolved promise
211 |
212 | ```javascript
213 | async function getMovieData() {
214 | var titanicPromise = $.getJSON('https://omdbapi.com?t=titanic&apikey=thewdb');
215 | var shrekPromise = $.getJSON('https://omdbapi.com?t=shrek&apikey=thewdb');
216 |
217 | var titanicData = await titanicPromise;
218 | var shrekData = await shrekPromise;
219 |
220 | console.log(titanicData);
221 | console.log(shrekData);
222 | }
223 |
224 | getMovieData();
225 | ```
226 |
227 | #### await with Promise.all
228 |
229 | We can use Promise.all to await multiple resolved promises
230 |
231 | ```javascript
232 | // we're waiting for an array of promises to resolve using the 'await' and Promise.all
233 | // Promise.all accepts an array of promises, and returns a promise which when resolved returns an array of resolved values
234 | // instead of .then and a callback, we can simply await the resolution of promise.all and then access those values in our moviesList array
235 | async function getMovieData(first, second) {
236 | var moviesList = await Promise.all([
237 | $.getJSON(`https://omdbapi.com?t=${first}&apikey=thewdb`);
238 | $.getJSON(`https://omdbapi.com?t=${second}&apikey=thewdb`);
239 | ]);
240 | console.log(moviesList[0].Year);
241 | console.log(moviesList[1].Year);
242 | }
243 |
244 | getMovieData('shrek', 'blade');
245 |
246 | // 2001
247 | // 1998
248 | ```
249 |
250 | ### Object Rest and Spread
251 |
252 | ES2015 provided the rest and spread operator for arrays
253 | - The rest operator was used as a parameter to functions and gathered the remaining arguments as an array
254 | - The spread operator was useful for spreading out values in an array as comma separated values
255 |
256 | #### Object Rest
257 |
258 | Gather remaining (rest) of keys and values in an object, and create a new one out of them
259 |
260 | ```javascript
261 | var instructor = {first: 'Elie', last: 'Schoppik', job: 'instructor', numSiblings: 3};
262 |
263 | // If we want to creates 'first' and 'last' variables, how can we collect the remaining keys and values? With rest operator
264 | var {first, last, ...data} = instructor; // destructuring the object
265 | first; // 'Elie'
266 | last; // 'Schoppik'
267 | data; // {job:'instructor', numSiblings:3}
268 | ```
269 |
270 | #### Object Spread
271 |
272 | Spread out keys and values from one object to another
273 |
274 | Great for creating new objects starting with default values and is a more concise alternative to Object.assign (but similar to it)
275 |
276 | ```javascript
277 | var instructor = {first: 'Elie', last: 'Schoppik', job: 'instructor'};
278 |
279 | // instructor2 will accept all of the keys and values of instructor and overwrite the first and last keys with 'Tim' and 'Garcia'
280 | var instructor2 = {...instructor, first:'Tim', last:'Garcia'};
281 |
282 | var defaults = {job: 'instructor', ownsCat: true, ownsDog: true};
283 | var matt = {...defaults, ownsCat: false};
284 | var colt = {...defaults, ownsDog: false};
285 | ```
--------------------------------------------------------------------------------
/advanced theory/advanced array methods.md:
--------------------------------------------------------------------------------
1 | # Advanced Array Methods
2 |
3 | #### Table of Contents
4 |
5 | - [Advanced Array Methods](#advanced-array-methods)
6 | - [Table of Contents](#table-of-contents)
7 | - [forEach](#foreach)
8 | - [map](#map)
9 | - [filter](#filter)
10 | - [some](#some)
11 | - [every](#every)
12 | - [reduce](#reduce)
13 |
14 | ## forEach
15 |
16 | - Iterates through an array
17 | - Runs a callback function on each value in the array
18 | - Returns 'undefined' ALWAYS when the loop ends (i.e. storing in a var or returning in a function won't work)
19 |
20 | ```javascript
21 | // array method callback each value&index entire
22 | // in the arr array
23 | [1, 2, 3].forEach(function(value, index, array) {
24 | // the callback will be executed 3 times since there are 3 values in the array
25 | // each time value and index are different
26 | // we can call parameters whatever we want
27 | // we don't always need all three parameters, but their order is important
28 | });
29 |
30 | // implementation of forEach
31 | function forEach(array, callback) {
32 | for (var i = 0; i < array.length; i++) {
33 | callback(array[i], i, array);
34 | }
35 | }
36 |
37 | // using forEach
38 | function halfValues(arr) {
39 | var newArr = [];
40 | arr.forEach(function(val) {
41 | newArr.push(val / 2);
42 | });
43 | return newArr;
44 | }
45 |
46 | halfValues[2, 4, 6]; // [1, 2, 3]
47 | ```
48 |
49 | ## map
50 |
51 | Basically it is forEach which transforms an array into another array with different values but of the same length
52 |
53 | - creates a new array
54 | - iterates through an array
55 | - runs a callback function for each value in the array
56 | - adds the result of that callback function to the new array
57 | - returns the new array
58 |
59 | ```javascript
60 | var arr = [1, 2, 3];
61 |
62 | arr.map(function(value, index, array) {
63 | return value * 2; // if no return, there is an array of undefined's
64 | });
65 |
66 | // [2, 4, 6]
67 |
68 | // implementation
69 | function map(arr, callback) {
70 | var newArr = [];
71 | for (var i = 0; i < arr.length; i++) {
72 | newArr.push(callback(arr[i], i, arr));
73 | }
74 | return newArr;
75 | }
76 |
77 | // usage
78 | // we could use forEach here, but map is a bit more friendly since it already returns a new array to us
79 | // forEach can be used if we want to overwrite values in an array or change something externally
80 | // when we would like a new array to be returned, especially one of the same length, map should always be used
81 | function tripleValues(arr) {
82 | return arr.map(function(value) {
83 | return value * 3;
84 | });
85 | }
86 |
87 | tripleValues([1, 2, 3]); // [3, 6, 9]
88 |
89 | function onlyFirstName(arr) {
90 | return arr.map(function(val) {
91 | return val.first;
92 | });
93 | }
94 |
95 | onlyFirstName([{first: 'Tim', last: 'Garcia'}, {first: 'Matt', last: 'Lane'}]);
96 |
97 | // ['Tim', 'Matt']
98 | ```
99 |
100 | ## filter
101 |
102 | .filter helps to return arrays of the same or smaller size
103 |
104 | - creates a new array
105 | - iterates through an array
106 | - runs a callback function on each value in the array
107 | - if the callback function returns trues, that value will be added to the new array
108 | - if the callback function returns false, that value will ve ignored from the new array
109 | - the result of the callback will ALWAYS be a boolean
110 |
111 | ```javascript
112 | var arr = [1, 2, 3];
113 |
114 | arr.filter(function(value, index, array) {
115 | // no need for an if statement, just return an expression that evaluates to true or false
116 | return value > 2;
117 | });
118 |
119 | // [3]
120 |
121 | var instructors = [
122 | {name: 'Elie'},
123 | {name: 'Tim'},
124 | {name: 'Colt'},
125 | {name: 'Matt'}
126 | ];
127 |
128 | instructors.filter(function(value, index, array) {
129 | return value.name.length > 3;
130 | });
131 |
132 | // [{name: 'Elie'}, {name: 'Colt'}, {name: 'Matt'}];
133 |
134 | // implementation
135 | function filter(array, callback) {
136 | var newArr = [];
137 | for (var i = 0; i < array.length; i++) {
138 | if (callback(array[i], i, array)) {
139 | newArr.push(array[i])l
140 | }
141 | }
142 | return newArr;
143 | }
144 |
145 | // usage
146 | function onlyFourLetters(arr) {
147 | return arr.filter(function(value) {
148 | return value.length === 4;
149 | });
150 | }
151 |
152 | onlyFourLetters(['Rusty', 'Matt', 'Moxie', 'Colt']); // ['Matt', 'Colt']
153 |
154 | function divisibleByThree(arr) {
155 | return arr.filter(function(value) {
156 | return value % 3 === 0;
157 | });
158 | }
159 |
160 | divisibleByThree([1, 2, 3, 4, 5, 6, 7, 8, 9]); // [3, 6, 9]
161 | ```
162 |
163 | ## some
164 |
165 | - iterates through an array
166 | - runs a callback on each value in the array
167 | - if the callback returns true for at least one single value, return true
168 | - otherwise, return false
169 | - the result of the callback will ALWAYS be a boolean
170 |
171 | ```javascript
172 | var arr = [1, 2, 3];
173 |
174 | arr.some(function(value, index, array) {
175 | return value < 2;
176 | });
177 |
178 | // true
179 |
180 | arr.some(function(value, index, array) {
181 | return value > 4;
182 | });
183 |
184 | // false
185 |
186 | // implementation
187 | function some(array, callback) {
188 | for (var i = 0; i < array.length; i++) {
189 | if (callback(array[i], i, array)) {
190 | return true;
191 | }
192 | }
193 | return false;
194 | }
195 |
196 | // usage
197 | function hasEvenNumber(arr) {
198 | return arr.some(function(value) {
199 | return value % 2 === 0;
200 | });
201 | }
202 |
203 | hasEvenNumber([1, 2, 3, 4]); // true
204 | hasEvenNumber([1, 3, 5]); // false
205 |
206 | function hasComme(str) {
207 | return str.split('').some(function(value) {
208 | return value === ',';
209 | });
210 | }
211 |
212 | hasComma('This is wonderful'); // false
213 | hasComma('This, is wonderful'); // true
214 | ```
215 |
216 | ## every
217 |
218 | - iterates through an array
219 | - runs a callback on each value in the array
220 | - if the callback returns true for every single value, return false
221 | - otherwise, return true
222 | - the result of the callback will ALWAYS be a boolean
223 |
224 | ```javascript
225 | var arr = [-1, -2, -3];
226 |
227 | arr.every(function(value, index, array) {
228 | return value < 0;
229 | });
230 |
231 | // true
232 |
233 | var arr = [-1, 2, -3];
234 |
235 | arr.every(function(value, index, array) {
236 | return value < 0;
237 | });
238 |
239 | // false
240 |
241 | // implementation
242 | function every(array, callback) {
243 | for (var i = 0; i < array.length; i++) {
244 | if (callback(array[i], i, array) === false) {
245 | return false;
246 | }
247 | }
248 | return true;
249 | }
250 |
251 | // usage
252 | function allLowerCase(str) {
253 | return str.split('').every(function(value) {
254 | return value === value.toLowerCase();
255 | });
256 | }
257 |
258 | allLowerCase('this is really nice'); // true
259 | allLowerCase('this is Really nice'); // false
260 |
261 | function allArrays(arr) {
262 | return arr.every(Array.isArray);
263 | }
264 |
265 | allArrays([[1], [2], [3, 4]]); // true
266 | arrArrays([[1], [2], {}]); // false
267 | ```
268 |
269 | ## reduce
270 |
271 | - accepts a callback and an optional second parameter
272 | - iterates through an array
273 | - runs a callback on each value in the array
274 | - the first parameter to the callback is either the first value in the array or the optional second parameter
275 | - the first parameter to the callback is often called 'accumulator'
276 | - the returned value from the callback becomes the new value of accumulator
277 | - whatever is returned from the callback function, becomes the new value of the accumulator
278 |
279 | ```javascript
280 | [1, 2, 3].reduce(function(accumulator, nextValue, index, array) {
281 | // [1, 2, 3] - array
282 | // reduce - method
283 | // function - callback
284 | // accumulator - first value in array or optional second parameter
285 | // second value in array or first, if optional second parameter is passed
286 | // index - each index in the array
287 | // array - the entire array
288 |
289 | // whatever is returned inside here, will be the value of accumulator in the next iteration
290 | }, optional second parameter)
291 |
292 | // example
293 | var arr = [1, 2, 3, 4, 5];
294 |
295 | arr.reduce(function(accumulator, nextValue) {
296 | return accumulator + nextValue;
297 | });
298 |
299 | // accumulator nextValue returned value
300 | // 1 2 3
301 | // 3 3 6
302 | // 6 4 10
303 | // 10 5 15
304 |
305 | // adding a second parameter
306 | var arr = [1, 2, 3, 4, 5];
307 |
308 | arr.reduce(function(accumulator, nextValue) {
309 | return accumulator + nextValue;
310 | // not returning - undefined
311 | }, 10);
312 |
313 | // accumulator nextValue returned value
314 | // 10 1 11
315 | // 11 2 13
316 | // 13 3 16
317 | // 16 4 20
318 | // 20 5 25
319 | ```
320 |
321 | Using reduce to return different data types
322 |
323 | ```javascript
324 | var names = ['Tim', 'Matt', 'Colt', 'Elie'];
325 |
326 | names.reduce(function(accumulator, nextValue){
327 | return accumulator += ' ' + nextValue;
328 | }, 'The instructors are');
329 |
330 | // accumulator nextValue returned value
331 | // The instructors are Tim The instructors are Tim
332 | // The instructors are Tim Matt The instructors are Tim Matt
333 | // ...
334 | // The instructors are Tim Matt Colt Elie
335 |
336 | var arr = [5, 4, 1, 4, 5];
337 |
338 | arr.reduce(function(accumulator, nextValue) {
339 | if (nextValue in accumulator) {
340 | accumulator[nextValue]++;
341 | } else {
342 | accumulator[nextValue] = 1;
343 | }
344 | return accumulator;
345 | }, {});
346 |
347 | // {5: 2, 4: 2, 1: 1}
348 | ```
349 |
350 | Usage of reduce
351 |
352 | ```javascript
353 | function sumOddNumbers(arr) {
354 | return arr.reduce(function(accumulator, nextValue) {
355 | if (nextValue % 2 !== 0) {
356 | accumulator += nextValue;
357 | }
358 | return accumulator;
359 | }, 0);
360 | }
361 |
362 | sumOddNumbers([1, 2, 3, 4, 5]); // 9
363 |
364 | function createFullName(arr) {
365 | return arr.reduce(function(accumulator, nextValue) {
366 | accumulator.push(nextValue.first + ' ' + nextValue.last);
367 | return accumulator;
368 | }, []);
369 | }
370 |
371 | createFullName([{first: 'Colt', last: 'Steele'}, {first: 'Matt', last: 'Lane'}]);
372 | // ['Colt Steele', 'Matt Lane']
373 | ```
--------------------------------------------------------------------------------
/advanced theory/AJAX.md:
--------------------------------------------------------------------------------
1 | # AJAX
2 |
3 | Asynchronous Javascript and XML
4 |
5 | #### Table of Contents
6 |
7 | - [AJAX](#ajax)
8 | - [Table of Contents](#table-of-contents)
9 | - [What Is AJAX](#what-is-ajax)
10 | - [XML and JSON](#xml-and-json)
11 | - [XML](#xml)
12 | - [JSON](#json)
13 | - [Requests](#requests)
14 | - [XMLHTTP Request (XHR)](#xmlhttp-request-xhr)
15 | - [Problems with XHR](#problems-with-xhr)
16 | - [Fetch](#fetch)
17 | - [Fetch Options](#fetch-options)
18 | - [Fetch Error Handling](#fetch-error-handling)
19 | - [Problem with Fetch](#problem-with-fetch)
20 | - [jQuery and Axios](#jquery-and-axios)
21 | - [jQuery](#jquery)
22 | - [$.ajax](#ajax)
23 | - [$.get](#get)
24 | - [$.post](#post)
25 | - [$.json](#json)
26 | - [Axios](#axios)
27 | - [Axios Error Handling](#axios-error-handling)
28 |
29 | ## What Is AJAX
30 |
31 | AJAX is not:
32 | - A library
33 | - A framework
34 | - A technology
35 |
36 | AJAX is an approach to webdev, a concept, a way of structuring apps
37 |
38 | It appeared it 2005 as a way to combine HTML, CSS, JS, DOM, XMLHTTP Requests and create apps that can update without refreshing
39 |
40 | With AJAX, websites can send and request data from a server in the background without disturbing the current page (led to today's single page apps with features like infinite scroll)
41 |
42 | Making requests with Javascript:
43 | - XMLHTTP Request
44 | - Fetch API
45 | - 3rd Party - jQuery, Axios, etc.
46 |
47 | ### XML and JSON
48 |
49 | They are data formats used in response data (mostly); API's don't respond with HTML, they respond with pure data
50 |
51 | #### XML
52 |
53 | Extended Markup Language
54 |
55 | Semantically similar to HTML, but it does not describe presentation like HTML does
56 |
57 | ```xml
58 |
59 | Some title
60 | Some author
61 |
62 | ```
63 |
64 | #### JSON
65 |
66 | JavaScript Object Notation replaced XML (so mostly it's now AJAJ); it looks almost exactly like JS Obj
67 |
68 | ```JSON
69 | 'item': {
70 | title: 'Some title',
71 | author: 'Some author'
72 | }
73 | ```
74 |
75 | ## Requests
76 |
77 | Workflow is usually event -> request -> data
78 |
79 | ### XMLHTTP Request (XHR)
80 |
81 | The first, original way to make requests (rarely used)
82 |
83 | ```javascript
84 | var XHR = new XMLHttpRequest(); // create new instance of request
85 |
86 | XHR.onreadystatechange = function() {
87 | // readyState can have 5 different states (from 0 to 4: unsent, opened, headers_receiver, loading, done)
88 | if (XHR.readyState == 4 && XHR.status == 200) {
89 | console.log(XHR.responseText);
90 | } else {
91 | console.log('There was a problem!');
92 | }
93 | };
94 |
95 | XHR.open('GET', 'https://api.github.com/zen'); // we tell what type of request we want to do, and URL
96 | XHR.send(); // what we send, we initiate request
97 | ```
98 |
99 | #### Problems with XHR
100 |
101 | 1. Ugly, bulky syntax
102 | 2. It's 16 years old
103 | 3. No Streaming
104 |
105 | ### Fetch
106 |
107 | Is a replacement, update for XHR
108 |
109 | ```javascript
110 | fetch(url) // basically, this is a request already; it returns a promise
111 | .then(function(res) {
112 | console.log(res); // whole response object; we can use something like res.status
113 | })
114 | .catch(function(error) {
115 | console.log(error);
116 | });
117 | ```
118 |
119 | Parsing JSON with Fetch:
120 |
121 | ```javascript
122 | fetch(url).then(function(res) {
123 | return res.json(); // it is promise as well (which is returned to .then after fetch(url))
124 | // .then (from below) can be inserted here as well (not after the closing brackets of the first .then)
125 | // functionally they are the same
126 | }).then(function(data) {
127 | console.log(data); // we can work with data as an object now
128 | }).catch(function() {
129 | console.log('Problem!');
130 | });
131 | ```
132 |
133 | #### Fetch Options
134 |
135 | ```javascript
136 | fetch(url, {
137 | method: 'POST', // get by default
138 | body: JSON.stringify({
139 | name: 'blue',
140 | login: 'bluecat',
141 | }) // including object with options
142 | // we don't have to use stringify, but it makes it easier, we don't have to make manualle eash of this a string, worry about " or '
143 | // also we can provide headers and other stuff, see more at https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
144 | })
145 | .then(function(response) {
146 | // do something
147 | })
148 | .catch(function(error) {
149 | // handle error
150 | });
151 | ```
152 |
153 | #### Fetch Error Handling
154 |
155 | Syntax:
156 |
157 | ```javascript
158 | .fetch(url)
159 | .then(function (res) {
160 | // we put error checking in its own .then
161 | // first thing we want to do is to ckeck if everything is ok
162 | if (!res.ok) {
163 | throw Error(404); // up to us
164 | // that will trigger .catch below
165 | }
166 | return res; // if things are ok, we return response and .then is run
167 | }).then(function (response) {
168 | console.log('ok');
169 | }).catch(function(error) {
170 | console.log(error);
171 | });
172 | ```
173 |
174 | Example:
175 |
176 | ```javascript
177 | var btn = document.querySelector('button');
178 |
179 | btn.addEventListener('click', function() {
180 | var url = 'https://api.github.com/users/coltasdas';
181 | fetch(url)
182 | .then(function() {
183 | console.log('EVERYTHING IS FINE!');
184 | })
185 | .catch(function() {
186 | console.log('There is a problem');
187 | // if the user is wrong (not 'Colt'), 'Everything is fine' will be returned anyway
188 | // we will see 'There is a problem' if there is a problem with a request itself, e.g. if the internet is off, or there is a problem connection, or with credentials, but not with the actual response
189 | });
190 | });
191 |
192 | // we need to rewrite our code to handle different statuses
193 |
194 | btn.addEventListener('click', function() {
195 | var url = 'https://api.github.com/users/coltasdas';
196 | fetch(url)
197 | .then(handleErrors)
198 | .then(function(request) {
199 | // to check the status we can put if request.status === 200... but we can use request.ok
200 | // request.ok is a built-in property which can be used instead of 'if status != 200' or something
201 | if (!request.ok) {
202 | // throw error
203 | console.log('Error with response status!')
204 | }
205 | // this code will still run
206 | console.log('EVERYTHING IS FINE!');
207 | })
208 | .catch(function() {
209 | console.log('There is a problem');
210 | });
211 | });
212 |
213 | // refactor using different promises to streamline things
214 | btn.addEventListener('click', function() {
215 | var url = 'https://api.github.com/users/coltasdas';
216 | fetch(url)
217 | .then(handleErrors)
218 | .then(function(request) {
219 | if (!request.ok) {
220 | throw Error(request.status);
221 | }
222 | return request // we need to return something if there is no error
223 | })
224 | .then(function(request) {
225 | console.log('Everything is fine');
226 | console.log(request);
227 | })
228 | .catch(function(error) {
229 | console.log(error); // equals to whatever we 'throw', i.e. here response status
230 | });
231 | });
232 |
233 | // refactor code
234 | var btn = document.querySelector('button');
235 | btn.addEventListener('click', function() {
236 | var url = 'https://api.github.com/users/coltasdas';
237 | fetch(url)
238 | .then(handleErrors)
239 | .then(function(request) {
240 | console.log('EVERYTHING IS FINE!');
241 | console.log(request);
242 | })
243 | .catch(function(error) {
244 | console.log(error);
245 | });
246 | });
247 |
248 | function handleErrors (request) {
249 | if (!request.ok) {
250 | throw Error(request.status);
251 | }
252 | return request;
253 | }
254 | ```
255 |
256 | #### Problem with Fetch
257 |
258 | The main problem is browser compatibility (IE doesn't have fetch at all)
259 |
260 | ---
261 |
262 | ## jQuery and Axios
263 |
264 | ### jQuery
265 |
266 | It can be used not only for manipulating the DOM, but for requests as well (without fetch)
267 |
268 | We need to include it first (look for jQuery CDN)
269 |
270 | #### $.ajax
271 |
272 | This is the main, 'base' method, other three are shorthand methods
273 |
274 | It just creates an XHR under the hood
275 | - https://api.jquery.com/jQuery.ajax/ (there are examples at bottom)
276 | - ``Query.ajaxSettings.xhr = function() {
277 | try {
278 | return new window.XMLHttpRequest();
279 | } catch ( e ) {}
280 | };``
281 |
282 |
283 |
284 | ```javascript
285 | $.ajax({
286 | method: 'GET',
287 | url: 'some.api.com',
288 | // datatype: 'json',
289 | })
290 | .done(function(res) {
291 | console.log(res);
292 | // data is automatically parsed (dataType parameter); we don't need to JSON.parse or data.json().then
293 | // default: intelligent guess, e.g. JSON
294 | // it's better to be explicit
295 | })
296 | .fail(function() {
297 | // do something
298 | // fail will automatically check response code, i.e. will trigger on 404, not only problem with request itself
299 | })
300 | ```
301 |
302 | #### $.get
303 |
304 | Load data from the server using a HTTP GET request ($.ajax method: 'get')
305 | - https://api.jquery.com/jQuery.get/
306 |
307 | ```javascript
308 | $("#getBtn").click(function(){
309 | $.get('https://api.github.com/users/colt')
310 | // note that parameters are strings, so jQuery.get( url [, data ] [, success ] [, dataType ] )
311 | .done(function(data){
312 | console.log(data);
313 | })
314 | .fail(function(){
315 | console.log("ERROR!");
316 | })
317 | });
318 | ```
319 |
320 | #### $.post
321 |
322 | Load data from the server using a HTTP POST request
323 | - https://api.jquery.com/jQuery.post/
324 |
325 | ```javascript
326 | $("#postBtn").click(function(){
327 | var data = {name: "Charlie", city: "Florence"};
328 | $.post("www.catsarecoolandsoaredogs.com", data)
329 | .done(function(data){
330 | console.log("HI!");
331 | })
332 | .fail(function(){
333 | console.log("ERROR!");
334 | })
335 | });
336 | ```
337 |
338 | #### $.json
339 |
340 | Load JSON-encoded data from the server using a GET HTTP request
341 | - https://api.jquery.com/jQuery.getJSON/
342 |
343 | ```javascript
344 | $("#getJSONBtn").click(function(){
345 | $.getJSON("https://api.github.com/users/colt")
346 | .done(function(data){
347 | console.log(data);
348 | })
349 | .fail(function(){
350 | console.log("PROBLEM!");
351 | })
352 | });
353 | ```
354 |
355 | ### Axios
356 |
357 | If we don't need whole jQuery (there are many features which could be not needed), we can use some other library for making request, such as Axios
358 |
359 | Axios is a lightweight HTTP request library (creates XHR under the hood; we need to install or include it first)
360 | - Make XMLHttpRequests from the browser
361 | - Make http requests from node.js
362 | - Supports the Promise API
363 | - Intercept request and response
364 | - Transform request and response data
365 | - Cancel requests
366 | - Automatic transforms for JSON data
367 | - Client side support for protecting against XSRF
368 | - https://github.com/axios/axios
369 |
370 | ```javascript
371 | // basic example
372 | axios.get(url)
373 | .then(function(res) {
374 | console.log(res.data)
375 | })
376 | .catch(function(e) {
377 | console.log(e);
378 | })
379 |
380 | // usage example (get)
381 | var url = 'https://opentdb.com/api.php?amount=1';
382 | axios.get(url)
383 | .then(function(res){
384 | console.log(res.data.results[0].question);
385 | })
386 | .catch(function(){
387 | console.log("ERR");
388 | })
389 | ```
390 |
391 | #### Axios Error Handling
392 |
393 | ```javascript
394 | // html:
395 | //
396 | //
397 | //
398 |
399 | var btn = document.querySelector("button");
400 | var section = document.querySelector("#comments");
401 | btn.addEventListener("click", sendRequest);
402 |
403 | function sendRequest(){
404 | axios.get("https://jsonplaaskjldceholder.typicode.com/comments", {
405 | params: {
406 | postId: 1 // we can pass in an object with parameters (instead of ?postId=1 etc.)
407 | }
408 | })
409 | .then(addComments)
410 | .catch(handleErrors)
411 | }
412 |
413 | function addComments(res) {
414 | res.data.forEach(function(comment) {
415 | appendComment(comment);
416 | });
417 | }
418 |
419 | function appendComment(comment) {
420 | var newP = document.createElement("p");
421 | newP.innerText = comment.email;
422 | section.appendChild(newP);
423 | }
424 |
425 | function handleErrors(err) {
426 | if (err.response) {
427 | // err.response if used for bad statuses
428 | console.log("Problem With Response ", err.response.status);
429 | } else if (err.request) {
430 | // err.request is used for bad requests
431 | console.log("Problem With Request!");
432 | } else {
433 | console.log('Error', err.message);
434 | }
435 | }
436 | ```
--------------------------------------------------------------------------------
/advanced theory/css3.md:
--------------------------------------------------------------------------------
1 | # CSS 3
2 |
3 | #### Table of Contents
4 |
5 | - [CSS 3](#css-3)
6 | - [Table of Contents](#table-of-contents)
7 | - [CSS Animations](#css-animations)
8 | - [Pseudoclasses](#pseudoclasses)
9 | - [:hover](#hover)
10 | - [:focus](#focus)
11 | - [:active](#active)
12 | - [Transform](#transform)
13 | - [Transform: Translate](#transform-translate)
14 | - [Transform: Scale](#transform-scale)
15 | - [Transform-Origin](#transform-origin)
16 | - [Transform: Rotate](#transform-rotate)
17 | - [Browser (Vendor) Prefixes](#browser-vendor-prefixes)
18 | - [Transitions](#transitions)
19 | - [Transition Shorthands](#transition-shorthands)
20 | - [What Can Be Transitioned](#what-can-be-transitioned)
21 | - [What Should Be Transitioned](#what-should-be-transitioned)
22 | - [Keyframes](#keyframes)
23 | - [CSS Animation Properties](#css-animation-properties)
24 | - [Animation Shorthand](#animation-shorthand)
25 | - [Layout With Flexbox](#layout-with-flexbox)
26 | - [Intro to Flexbox](#intro-to-flexbox)
27 | - [Display: Flex Property](#display-flex-property)
28 | - [Flex Terminology](#flex-terminology)
29 | - [Flexbox Properties of Container](#flexbox-properties-of-container)
30 | - [Flex-direction](#flex-direction)
31 | - [Flex-wrap](#flex-wrap)
32 | - [Justify-content](#justify-content)
33 | - [Align-items](#align-items)
34 | - [Align-content](#align-content)
35 | - [Flexbox Properties of Item](#flexbox-properties-of-item)
36 | - [Align-self](#align-self)
37 | - [Order](#order)
38 | - [Flex](#flex)
39 | - [Flex-basis](#flex-basis)
40 | - [Flex-grow](#flex-grow)
41 | - [Flex-shrink](#flex-shrink)
42 | - [Holy Grail Layout](#holy-grail-layout)
43 | - [Flexbox Browser Support](#flexbox-browser-support)
44 | - [Responsiveness](#responsiveness)
45 |
46 | ## CSS Animations
47 |
48 | ### Pseudoclasses
49 |
50 | Usually animations are triggered by something, they do not happen on page load
51 |
52 | Pseudoclasses are commonly used triggers, special selectors which are added to selector and specify a special state of the selected elements (not only related to animations)
53 | - They let you apply a style to an element not only in relation to the content fo the document tree, but also in relation to external factors, e.g.
54 | - History of the navigator (:visited)
55 | - Status of the content (:checked)
56 | - Position of the mouse (:hover)
57 |
58 | Syntax:
59 |
60 | ```css
61 | selector:pseudo-class {
62 | property: value;
63 | }
64 | ```
65 |
66 | #### :hover
67 |
68 | Trigger by a user mousing over (not necessarily activating it)
69 |
70 | ```css
71 | div:hover {
72 | background: purple;
73 | }
74 | ```
75 |
76 | #### :focus
77 |
78 | Triggers when an element 'receives focus' (triggered when the user clicks, taps on an element or selects with 'tab')
79 |
80 | ```css
81 | input:focus {
82 | color: red;
83 | }
84 | ```
85 |
86 | #### :active
87 |
88 | Triggers when an element is 'being activated by user' (click on an element (actual action is happening) or when it's selected by 'tab', commonly used on \ or \