├── LICENSE
├── README.md
├── fundamental
├── functional-programming.md
├── isomorphic-webapp.md
├── object-oriented-programming.md
├── scoping-and-closure-in-javascript.md
├── tech-behind-modern-webapps.md
└── why-work-with-go.md
└── guides
├── auth-setup.md
├── coding-best-practice.md
├── d3-react-integration.md
├── es6-and-babel.md
├── git-tutorial.md
└── react-notes.md
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Xiaoyun Yang
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # web-dev-cheatsheets
2 |
3 | ## Fundamental
4 | * [technology behind modern webapps](/fundamental/tech-behind-modern-webapps.md)
5 | * [Building an isomorphic webapps](/fundamental/isomorphic-webapp.md)
6 | * [Closure and Scope](/fundamental/scoping-and-closure-in-javascript.md)
7 | * [Functional Programming](/fundamental/functional-programming.md)
8 | * [D3 and Integration With React](/guides/d3-react-integration.md)
9 | * [Object Oriented Programming](/fundamental/object-oriented-programming.md)
10 | * How to [write testable code](http://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf) - [web version](http://misko.hevery.com/code-reviewers-guide/)
11 | * Two pillars of programming [Part1](https://medium.com/javascript-scene/the-two-pillars-of-javascript-ee6f3281e7f3)
12 |
13 | ## Guides
14 |
15 | * [ES6 and Babel](/guides/es6-and-babel.md)
16 | * [Authentication Setup](/guides/auth-setup.md)
17 | * [React Notes](/guides/react-notes.md)
18 | * [Git Tutorial](/guides/git-tutorial.md)
19 | * [Javascript coding best practice](/guides/coding-best-practice.md)
20 | * [Modern JS Cheatsheet](https://github.com/mbeaudru/modern-js-cheatsheet) 😍
21 | * [Wearhive's List Of Best Practices for JavaScript Projects](https://github.com/wearehive/project-guidelines#readme) 😍
22 | * [Developer Roadmap](https://github.com/kamranahmedse/developer-roadmap)
23 | * [Free javascript books](https://jsbooks.revolunet.com/)
24 | * Airbnb's [JavaScript Style Guide](https://github.com/airbnb/javascript)
25 | * Google's [Style Guide for HTML and CSS](https://google.github.io/styleguide/htmlcssguide.html#ID_and_Class_Name_Delimiters)
26 | * [Case Study](https://docs.google.com/document/d/1ihmYy7mwGY7SuRix774VcDoYpRbvgZdmM1lapbiuv6g/edit) for how to create a good landing page with good SEO and UX 👍
27 | * [TLDR Addy Osmani Design Patterns](https://github.com/karlpatrickespiritu/TLDR-Learning-JS-Design-Patterns-by-Addy-Osmani) 👍
28 |
29 | ## Keep up with Latest Stack
30 | * [Stackshare 2017 Post](https://stackshare.io/posts/top-developer-tools-2017)
31 | * [JavaScript 2017]()
32 | * [UI Framework for your react app](https://hackernoon.com/the-coolest-react-ui-frameworks-for-your-new-react-app-ad699fffd651)
33 | * [react.sketch.app](http://airbnb.io/react-sketchapp/?ref=stackshare)
34 |
--------------------------------------------------------------------------------
/fundamental/functional-programming.md:
--------------------------------------------------------------------------------
1 | ## Motivation
2 |
3 | __Why Learn Functional Programming (FP)?__
4 |
5 | Let's start with a simple motivating example to demonstrate the key differences between functional programming and imperative programming.
6 |
7 | Suppose you want to find the average of a list of Ints. In imperative programming, you would do something like this:
8 |
9 | ```java
10 | //In Java
11 | double[] arr = new double[] {1,2,3};
12 | double acc = 0;
13 | for(int i=0; i The average of [1.0, 2.0, 3.0] is 2.0
20 | ```
21 |
22 | The functional programming solution is much shorter and higher level:
23 |
24 | ```scala
25 | //In Scala
26 | def list = List(1.0, 2.0 ,3.0)
27 | def findAve(l: List[Double]): Double = l.reduce(_ + _)/l.length
28 | findAve(List(1,2,3))
29 |
30 | println(s"The average of $list is $ave")
31 | //> The average of List(1.0, 2.0, 3.0) is 2.0
32 | ```
33 |
34 | 30 years ago, the emphasis was on creating and maintaining small code base that need to fulfill a set of functional requirements. Computational power was a huge constraint. Now we live in a different world. We build complex programs with many moving parts. Programs are expected to be reliable, responsive, and error resistant. Servers are scattered throughout the world so things like latency and multicore programming became the new pain points.
35 |
36 | The most visible benefits of functional programming are:
37 |
38 | * __developer productivity__ - better code reusability and modularity, which is made possible by treating functions as composable primitives and something that describes behavior in the abstract (i.e., without binding it to actual use cases or data).
39 | * __Program correctness__ - a benfit of referential transparency
40 | * __Scalability__ - program correct whether run on one core or multiple cores (another benefit of referential transparency)
41 |
42 | __Why Now?__
43 |
44 | * 1950s -
45 | Functional programming was invented, but not popular because it took more memory to be stateless. Memory was expensive.
46 | * 1980s - Object Oriented Programming (OO) became popular in the 80s because GUIs became popular. In OO style, it’s easier to program things that use a fixed number of operations for an unlimited number of operation.
47 | * 2010s - Memory is cheap. Can’t make transistors any smaller (marginal gains in hardware capability). Fast processing and big data processing requires more than one core. There has been an increasing emphasis on asynchronous, distributed, multi-core and use cloud computing. Multicore competing for the same memory bus, OS no longer manages threads for you on multicore - if you need to perform the same tasks faster and faster, you can increase to unlimited number of cores. Stateful programming is more of a liability now with these new requirement.
48 | Functional ➡ no assignments ➡ no states ➡ no blocking or concurrency issues.
49 |
50 | In the words of [SICP](https://mitpress.mit.edu/sites/default/files/6515.pdf), a Program is a pattern of rules to direct processes that manipulate data. The functional programming paradigm helps us:
51 |
52 | > use higher order functions to capture patterns in usage.
53 |
54 | > control complexity by building abstractions that hide details when appropriate.
55 |
56 | > Programs must be written for people to read and only incidentally for machines to execute.
57 |
58 |
59 | ## Key (and cool) Ideas From FP
60 |
61 | This section talks about how to use functional programming concepts to design robust software programs. Ideas from this section are inspired by [This Video](https://www.youtube.com/watch?v=E8I19uA-wGY) and [This Book](https://www.manning.com/books/functional-programming-in-scala)
62 |
63 |
64 | ### Functional Programming Design Patterns
65 |
66 | In the functional programming paradigm, we want to get away from hard coding values or function behaviors. Thus, we parameterize the behavior as another function. How do we do that? We have to start thinking about functions as something configurable and composable. These are the bread and butter concepts that FP-ers must come to embrace as a way of life:
67 |
68 |
69 | * __Functions__: In FP, we think of our programs as pipes for data to travel through. Functions can be inputs and outputs.
70 |
71 | * __Higher Order Functions (HOFs)__: Probably the coolest and most useful concept in FP. A HOF is simply a function that takes another function as input.
72 |
73 | * __Polymorphic Functions__: If functions are pipes, think of a polymorphic function as a design for a pipe that can be used to make different types of pipes. Instead of creating a new function from scratch, you can "configure" a polymorphic function (sometimes called a generic function) to serve specific purpose of the function. We can "abstract out" the polymorphic function from observing the structural similarities between different functions.
74 |
75 | Below is a common pattern that illustrates these three concepts:
76 |
77 | __The Loop Pattern__
78 |
79 | Let's look at what’s in common between the two loop functions and what’s distinct between them.
80 |
81 | * Common: Take an array of *stuff* and combine them.
82 | * Distinct: The initial value and what the types of data you work on are different.
83 |
84 | ```javascript
85 | //in javascript
86 |
87 | //A loop - prints "1 2 3" to console
88 | var res = 0
89 | let nums = [1, 2, 3]
90 | for(i=0; i (a+b), 0) //> 6
113 | ["a", "b", "c"].reduce((a,b) => a+b, "") //> "abc"
114 | ```
115 |
116 | `reduce` is actually a __HOF__ that javascript [gives you for free](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce?v=a). What makes it a HOF is that it takes another function as an argument, i.e., `(a,b) => a+b`. In this example, we are being lazy by not declaring this function first (e.g., assigning to a const called `addTwo`) prior to using it as an argument in `reduce`. It is perfectly fine to leave that function without a name, that is *anonymous*, because it's simple and short enough that we can declare it directly in the `reduce` function. The `(a,b,) => a+b` is called an __anonymous function__.
117 |
118 | `reduce` is also a __polymorphic function__. It does not hardcode behavior and lets you use it on any array of *stuff* and reduce it by specifying a rule (e.g., `(a,b) => a+b`).
119 |
120 | However, if we want to be using the rule with this exact rule a lot, it may be useful to "configure" the `reduce` function to some more specific function for brevity and convenience. As shown below, `myReduce` can be used on both arrays of strings and arrays of numbers.
121 |
122 | ```javascript
123 | const myReduce = (arr, initVal) =>
124 | arr.reduce((a,b) => (a+b), initVal)
125 |
126 | let arr1 = [1,2,3]
127 | let arr2 = ["a", "b", "c"]
128 | myReduce(arr1, 0) //> 6
129 | myReduce(arr2, "") //>"abc"
130 |
131 | ```
132 |
133 | What happens if we do this?
134 |
135 | ```javascript
136 | let arr3 = [arr1, arr2]
137 | myReduce(arr3, [])
138 | ```
139 |
140 | The above is going to evaluate to `"1,2,3a,b,c"`. Why is that?
141 |
142 | It turns out in javascript, if you want to concatenate arrays, you have to use `arr.concat`:
143 |
144 | ```javascript
145 | let arr3 = [arr1, arr2]
146 | arr3.reduce((a,b) => a.concat(b), [])
147 |
148 | ```
149 | That may seem counterintuitive because when you use `+` on strings, you are essentially concatenating. Not to mention that fundamentally, strings are just an array of chars.
150 |
151 | In scala, the `++` is used for concatenation of any collections, although the result is going to differ based on how you use it as shown below:
152 |
153 | ```scala
154 | //In Scala
155 | List(1,2,3) ++ List("a", "b", "c") //> res: List[Any] = List(1, 2, 3, a, b, c)
156 |
157 | List(1,2,3) ++ "abc"
158 | //> res: List[AnyVal] = List(1, 2, 3, a, b, c)
159 |
160 | "abc" ++ List(1,2,3)
161 | //res: scala.collection.immutable.IndexedSeq[AnyVal] = Vector(a, b, c, 1, 2, 3)
162 |
163 | "abc" ++ "def" //> res: String = abcdef
164 | "abc" + "def" //> res: String = abcdef
165 | ```
166 |
167 | __Function Composition and Partial Application (Currying)__
168 |
169 | The idea of Currying is named after the mathematician Haskell Curry. He also discovered one of the most important results in computer science, the Curry-Howard isomorphism which says that a program is a logical proof, and the hypothesis that it proves is its type.
170 |
171 | ```scala
172 | //Currying is when you break down a function that takes multiple arguments into a
173 | //series of functions that take part of the arguments.
174 | //converts a function f of two arguments into a function of one argument that partially applies f.
175 | def curry[A,B,C](f: (A,B) => C): A => (B => C) =
176 | (a: A) => (b: B) => f(a,b)
177 | //> curry: [A, B, C](f: (A, B) => C)A => (B => C)
178 | ```
179 |
180 | Bottomline: Partial application lets you make reusable functions.
181 |
182 | ### Types
183 |
184 | An interesting observation from the sample code above shows that Scala distinguishes between many types of values while javascript has just a few, i.e., `var` (mutable, global), `const` (immutable) or `let` (mutable, local). This brings up another interesting feature of FP - Types. As quoted from [This Video](https://www.youtube.com/watch?v=E8I19uA-wGY):
185 |
186 | > Type are not classes. Types are just the label for the set of inputs or the set of outputs. Classes are a collection of functions, Types can be composed.
187 |
188 | Scala is type-safe, which is the biggest selling point for Scala according to [LightBend](https://www.lightbend.com/) (formerly TypeSafe) - the company founded by the creator of Scala. Using the findAve example from earlier, type safe means you can impose the argument type and return type when you first define your function in Scala.
189 |
190 | ```scala
191 | def findAve(l: List[Double]): Double = l.reduce(_ + _)/l.length
192 | findAve(List(1,2,3))
193 | ```
194 | Look What happens in a language that's not type safe. Suppose you have a text input to get the user to enter a number `num`, then your program subtracts 1 from `num`.
195 |
196 | ```javascript
197 | //In javascript
198 | let num = "7" //user inputs "7" for num
199 | let res = num - 1 //> 6 ... good
200 |
201 | let num = "07" //user inputs "07" for num
202 | res = num - 1 //>6 ... still good
203 |
204 | let num = "apple" - 1 //> NaN
205 | res = num - 1 //> NaN ... bad
206 |
207 | ```
208 |
209 | In a type-safe language like scala, subtracting 1 from a String doesn't make sense. However, in javascript, it works - but only if the String represents a number.
210 |
211 | When the language is not type-safe, it's up to the programmer to ensure that the string indeed represents a number. Also, javascript is dynamically typed so the compiler won't help you catch this type of error. Errors would come up during run-time depending what that string is, which could lead to some nasty bugs.
212 |
213 | Suppose you leave out the return type `Double` in the function signature. Scala can deduce that the return type is based on the argument type.
214 | ```scala
215 | def findAve(l: List[Double]) = l.reduce(_ + _)/l.length
216 | //> findAve: (l: List[Double])Double
217 | ```
218 |
219 | Type inference is pretty convenient at time and some languages like javascript do a good job making type inferences.
220 |
221 | However, omiting the type of your data can be the source of some nasty bugs such as the one demonstrated below in javascript. javascript seems to automatically convert your argument type from int to double.
222 |
223 | ```javascript
224 | //In javascript
225 | let findAve = arr => arr.reduce((a,b) => a+b)/arr.length
226 |
227 | findAve([1,2,3]) //> 2
228 | findAve([1,1,3]) //>1.6666666666666667
229 | ```
230 |
231 | ```scala
232 | //In Scala
233 | def findAve(l: List[Int]) = l.reduce(_ + _)/l.length
234 | //> findAve: (l: List[Int])Int
235 |
236 | findAve(List(1,2,3)) //> 2
237 | findAve(List(1,1,3)) //> 1
238 |
239 | def findAve2(l: List[Int]): Double = l.reduce(_ + _)/l.length
240 | findAve2(List(1,1,3)) //> 1.0
241 |
242 | def findAve3(l: List[Double]): Double = l.reduce(_ + _)/l.length
243 | findAve: (l: List[Double])Double
244 | findAve(List(1,1,3)) //>1.6666666666666667
245 | ```
246 |
247 |
248 | __Pattern Matching__
249 |
250 |
251 | __Recursion__
252 |
253 |
254 | ### Referential Transparency (RT)
255 |
256 | As [FP in Scala](https://github.com/fpinscala/fpinscala/wiki/Chapter-1:-What-is-functional-programming%3F) puts it:
257 | > Referential transparency forces the invariant that everything a function does is represented by the value that it returns, according to the result type of the function. At each step we replace a term with an equivalent one; computation proceeds by substituting equals for equals. In other words, RT enables equational reasoning about programs.
258 |
259 | I like the second definition better:
260 | > Another way of understanding RT is that the meaning of RT expressions does not depend on context and may be reasoned about locally, whereas the meaning of non-RT expressions is context-dependent and requires more global reasoning.
261 |
262 | The obvious benefit is RT makes the program less prone to bugs. Since RT forces data immutability, making a change to your data requires you to create new data, which hurts memory performance. Similar to recursion, there are things "under the hood" that can be done to improve memory performance while still enforcing immutability at a high level.
263 |
264 | We want to write referential transparent programs to avoid side effects. What are side effects and what are the dangers of side effects? See Monad section below for more on this.
265 |
266 |
267 | ### Laziness
268 | Laziness and memoization could be translated to two obvious principles:
269 |
270 | * Laziness = “Don’t compute something until you need it.”
271 | * Memoization = “Don’t recompute something you have computed before.”
272 |
273 | __Closure__
274 |
275 | When you declare a local variable, that variable has a scope. Generally local variables exist only within the block or function in which you declare them.
276 |
277 | A closure is a persistent local variable scope.
278 |
279 | ### Monad
280 | Now you understand higher order functions and types, you are ready for learning what a monad is. Instead of hard coding error handlers in your code to deal with non-deterministic nature of real world applications, you delegate the error handling to monads, which are implemented as a type in Scala. Another way to think about the monad is that [a monad is simply a wrapper](https://medium.com/@sinisalouc/demystifying-the-monad-in-scala-cc716bb6f534).
281 |
282 | There are typically four types of monads to express four types of side effects:
283 |
284 | A naive way to handle non-determinism is by writing code with lots of side effects.
285 |
286 | > A side effect is any application state change that is observable outside the called function other than its returned value. ~ [Eric Elliott](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0)
287 |
288 | Java web applications from the early 2000s are littered with try/catch blocks to guard against unintended/undesirable program states due to external processes (e.g., user input or loss of network connectivity). This practice often implies lots of boilerplate code that are error prone and results in the _blocking_ of operations downstream until the necessary information is obtained.
289 |
290 | Many programs designed with a user interface are especially at risk of side effects. A tell tale sign is anytime your function is reading or modifying external variable (e.g., a global variable) outside its own function scope. These external variables include:
291 |
292 | * Reading user input
293 | * Writing to a file
294 | * Reading from a network
295 | * Reliance on a global state variable (Note: reading/modifying global variables/states is a necessary evil in many real time embedded systems due to microprocessor constraints; however, you should not be doing that if your distributed software is not running on microprocessors.)
296 |
297 | How do side effects hurt developer productivity and program correctness?
298 |
299 | Side effects makes it difficult for you to reason about the correctness of your program locally. If you have a referentially transparent function (i.e., free of side effects), then you can look at your function and know exactly what it does, meaning the proof of correctness may be limited to the case of testing the response of the function to given inputs. When your program is not referentially transparent, you need to obtain knowledge about external processes, global variables/states, and there is no way to prove correctness of your function by simply running unit tests. You need to run acceptance testing and user testing every time you make a small change in a function. This can have _expensive_ ramification in the real world.
300 |
301 | We don't want to get rid of the interesting parts of our program (e.g., user interface) in fear that they will introduce side effects into our program. Rather we want to introduce FP design patterns into our programs to protect us from the negative consequences of side effects. How do we do that? Monads.
302 |
303 | There are typically four types of monads to express four types of side effects:
304 |
305 | 1. Exception - Takes into account operations that can fail. The exception monad is [implemented](http://blog.xebia.com/try-option-or-either/) using `Option`, `Either`, or `Try` in Scala.
306 | 2. Future - Takes into account that computation takes time (latency). The future monad is implemented using `Future` in Scala, which does a callback when the task is complete.
307 | 3. Iterable - Reacting to synchronous data streams.
308 | 4. Observable - Reacting to asynchronous data streams.
309 |
310 |
311 | ### Monoid
312 |
313 | The idea of monoid is actually simple. You'd encounter a monoid in your day-to-day programming without even realizing it's called a monoid. I've encountered it the other day while trying to determine whether there is a non-empty string in my collections of arrays.
314 |
315 | ```javascript
316 | //In javascript
317 |
318 | let arr1 = [""]
319 | let arr2 = ["", ""]
320 | let arr3 = ["", "", "a"]
321 |
322 | let res1 = arr1.reduce((a,b) => a+b) //> ""
323 | let res2 = arr2.reduce((a,b) => a+b) //> ""
324 | let res3 = arr3.reduce((a,b) => a+b) //> "a"
325 |
326 | const strLen = arr =>
327 | arr.reduce((a,b) => a+b).length
328 |
329 | strLen([res1]) //> 0
330 | strLen([res1, res2]) //> 0
331 | strLen([res1, res2, res3]) //> 1
332 | strLen([res3, res2, res1]) //> 1
333 | ```
334 |
335 | What do we notice?
336 |
337 | * The function `isEmpty` will provide the same correct result no matter whether the ``"a"`` lives in `arr1`, `arr2` or `arr3`. The result does not hinges on the groupings of the strings (Associativity).
338 | * The final result does not care how many empty strings you have as any string `s` concatenated with the empty string is that string (i.e., `s + "" == s`). However, having a single non-empty string changes your result.
339 | * The order in which the string inputs are provided to the function `isEmpty` does not impact the final result (Commuativity).
340 |
341 | This is recipe for correctness in asynchronous programming and parallel computing.
342 |
343 | Because how you group the things over which you want to compute doesn't matter and the order of computing doesn't matter, you can calculate the final result by assigning the subproblems to be calculated by different processors and combine the final answer at the end.
344 |
345 | The most [common monoids](https://www.safaribooksonline.com/blog/2013/05/15/monoids-for-programmers-a-scala-example/) are:
346 |
347 | * Integers with addition.
348 | * Strings with concatenation.
349 | * Lists with concatenation, like `List(1,2)+List(3,4) == List(1,2,3,4)`.
350 | * Sets with their union, like `Set(1,2,3)+Set(2,4) == Set(1,2,3,4)`.
351 |
352 | Bottomline: Why do we care about monoids at all? You can use the monoid laws to verify correctness of your program (esp. when your program deals with aggregating data and operations) under asynchronous conditions and evaluate whether the behavior of your program is going to change if you tried to use parallel computing to optimize for speed and load distribution.
--------------------------------------------------------------------------------
/fundamental/isomorphic-webapp.md:
--------------------------------------------------------------------------------
1 | # Building Isomorphic Webapp
2 |
3 | You will need:
4 |
5 | * React - view provider
6 | * Redux - manages business logic for the view provider
7 | * Express - server framework
8 | * Node - server engine
9 | * Babel - ES6 transpiler
10 | * Webpack - packager
11 |
12 | The book: [Isomorphic Web Applications Chapter 1](https://livebook.manning.com/#!/book/isomorphic-web-applications/chapter-1/v-10/106)
13 |
14 | ## What is isomophic Webapp
15 |
16 | ### Background
17 |
18 | [https://blog.tableflip.io/server-side-rendering-with-react-and-redux/](https://blog.tableflip.io/server-side-rendering-with-react-and-redux/)
19 | > Traditionally if you’re serving a website, a request will come into your server, and your app will gather all the data it needs to render the page and then use Handlebars or Jade or whatever to smoosh the two together and send the resultant HTML down to the browser. If you’re using a client side app like react, you get the templates sent to you first, and then you request the data for that page (from your API). Maybe you do an initial render in between, show a nice spinner or something, but when that data finally comes back, you do a re-render to show the page you wanted.
20 | >
21 | > We all want it - the Holy Grail of having your app render server side to give your users a quicker initial rendering and to help SEO. The problem is that React doesn’t fit with the traditional model for server side rendering, in fact React turns it on it’s head.
22 |
23 | When you create a webpage, there will be static content and there will be dynamic content.
24 |
25 | 
26 |
27 | Static content is stuff on the webpage that will not change. For example, the topnav and the footer are things that are static.
28 |
29 | Dynamic content is stuff that changes after the DOM has loaded. For example, push notifications.
30 |
31 | ### Isomorphic Webapp
32 |
33 | > isomorphic web apps are the result of combining server-rendered HTML pages with single-page application architecture.
34 |
35 | Isomorphic webapp means have server side rendering for the static content and single page applications rendering dynamic content.
36 |
37 | 
38 |
39 | Isomorphic webapps are like SPAs, but has the capability to choose what to render dynamically in the browser. This is achieved through server-side rendering.
40 |
41 | Three main steps in an isomorphic app:
42 |
43 | 1. server render
44 | - The server gets an initial request via a HTTP GET request. The server grabs what it needs to render the HTML, such as data from a database or static assets like images, then sends HTML to the browser.
45 | - Initial request is generated when the the user clicks a link to your website or types the URL (address) to your website directly into the web address bar.
46 | 2. initial browser render
47 | -
48 | 3. single-page application behavior
49 | - Once the page enters into Single Page Application (SPA) mode, updates are initiated by events, usually from the user.
50 |
51 | [Isomorphic vs. Universal app](https://medium.com/@ghengeveld/isomorphism-vs-universal-javascript-4b47fb481beb)
52 | >Isomorphism is the functional aspect of seamlessly switching between client- and server-side rendering without losing state. Universal is a term used to emphasize the fact that a particular piece of JavaScript code is able to run in multiple environments.
53 |
54 | ### Why is SPA useful?
55 | > SPA lets you have interesting webpages that handle complex user interactions.
56 |
57 | Ajax (Asynchronous JavaScript and XML) makes communication with the server asynchronous so that data is transferred and processed in the background, allowing the user to interact with other parts of a page without interruption. This improves usability and responsiveness.
58 |
59 | When a user navigates to a new view, additional content required for the view is requested using an XHR (XMLHttpRequest), typically communicating with a server-side REST API or endpoint.
60 |
61 | What really defines an SPA as such, is the fact that client-side JS handles the routing instead of the browser. Daniel Puplus explains the advantages of SPAs in [Building Single Page Applications](https://writing.pupius.co.uk/beyond-pushstate-building-single-page-applications-4353246f4480):
62 |
63 | 1. **Good**: History and fast back
64 | > When a user presses the browser’s back button they expect the change to happen quickly and for the page to be in a similar state to how it was last time they saw it.
65 | >
66 | > once the app is initially loaded, it can support quick navigation between pages without refreshing the page, and if done right, can even work offline. ~ [airbnb engineering article](https://medium.com/airbnb-engineering/isomorphic-javascript-the-future-of-web-apps-10882b7a2ebc)
67 |
68 | 2. **Good**: Save scroll position
69 | > When the user navigates using the browser’s forward or back button the scroll position should be the same as it was last time they were on the page.
70 |
71 | 3. **Good**: XMLHttpRequest (XHR)
72 |
73 | 4. **Good**: Fast response to user input
74 |
75 | > Apps like Gmail, the classic example of the single-page app, could respond immediately to user interactions, no longer needing to make a round-trip to the server just to render a new page.
76 |
77 | SPA was popular in 2013. But over time, the disadvantages of SPA became hard to ignore.
78 |
79 | [The disadvantages of a single page application](https://adamsilver.io/articles/the-disadvantages-of-single-page-applications/) include:
80 |
81 | 1. **Bad**: SEO
82 |
83 | > For many SPAs, SEO is an afterthought, which is problematic because retro fitting server side rendering is not trivial. The alternative is to create a special website just for bots which isn’t ideal either.
84 |
85 | > Web crawlers function by making a request to a web server and interpreting the result; but if the server returns a blank page, it’s not of much value. There are workarounds, but not without jumping through some hoops. ~ [airbnb engineering article](https://medium.com/airbnb-engineering/isomorphic-javascript-the-future-of-web-apps-10882b7a2ebc)
86 |
87 | 2. **Bad**: Memory leaks and long load time.
88 | > If an SPA grows to a significant size, loading the entire application on load will be slow.
89 |
90 | Also, loading a SPA can be a slow experience for a user (especially on mobile phones). Faster and improved accessibility because the user can view the app without JavaScript.
91 |
92 | > The bulk of the application logic (views, templates, controllers, models, internationalization, etc.) lives in the client, and it talks to an API for data. The server could be written in any language, such as Ruby, Python, or Java, and it mostly handles serving up an initial barebones page of HTML. Once the JavaScript files are downloaded by the browser, they are evaluated and the client-side app is initialized, fetching data from the API and rendering the rest of the HTML page. ~ [airbnb engineering article](https://medium.com/airbnb-engineering/isomorphic-javascript-the-future-of-web-apps-10882b7a2ebc)
93 |
94 | 3. **Bad**: It [breaks the web](https://ponyfoo.com/articles/stop-breaking-the-web)
95 |
96 | > Hash routing sucks. It does nothing to help modern browsers (except slowing down the experience, it does do that!) and everything to complicate development and confuse humans who are using older browsers.
97 |
98 | ### Why is server side rendering useful?
99 | > server side rendering is ideal for SEO.
100 |
101 | Bots and crawlers can read all of the data on page load. We need good SEO to maximize the number of people that come to the app from search engines. Single-page applications are difficult for search engine bots to crawl because they don’t load the data for the app until after the JavaScript has run in the browser.
102 |
103 | Google tools for assessing your app for SEO
104 |
105 | * Use Google Speed Insight Tool to assess speed of your web page:
106 | [https://developers.google.com/speed/pagespeed/insights](https://developers.google.com/speed/pagespeed/insights)
107 | * Use Google lighthouse for an in depth anaysis: [https://developers.google.com/web/tools/lighthouse/](https://developers.google.com/web/tools/lighthouse/)
* Build a progressive webapp to improve usability for the mobile version of your webpage. [Addy Osamani](https://addyosmani.com/blog/getting-started-with-progressive-web-apps/) wrote extensively about progressive webapps.
108 | * Use Audit in Chrome's devtools. Build a progressive Web Apps take advantage of new technologies to bring the best of mobile sites & native apps to users. Read [Progressive Webapps with React](https://medium.com/@addyosmani/progressive-web-apps-with-react-js-part-i-introduction-50679aef2b12).
109 |
110 | Client side rendering is slow
111 |
112 | > because the human now has to download all of your markup, your CSS, and your JavaScript before the JavaScript is able to render the view the user expected you to deliver in the first place.
113 |
114 | > you should be delivering the content in human-viewable form first, and not after every single render blocking request out there finishes loading. This means that a human-ready HTML view should be rendered in the server-side and served to the human, then you can add your fancy JavaScript magic on top of that, while the user is busy making sense of the information you’ve presented them with. ~[stop breaking the web](https://ponyfoo.com/articles/stop-breaking-the-web)
115 |
116 |
117 | ## React
118 | > React’s virtual DOM lets us render HTML on the server.
119 |
120 | React is a declarative, efficient, and flexible JavaScript library for building user interfaces.
121 |
122 | In React, components are the basic building blocks, they encapsulate markup and logic together in one place. Components receive immutable data (called props) from parent components. There's a top-level parent component, which we will refer to as the `Provider`.
123 |
124 | React takes advantage of functional concepts by adhering to single direction data flows from the top level component down to its children. What makes it appealing for isomorphic apps is how it uses a virtual DOM to manage changes and updates to the application
125 |
126 | React uses a template language called JSX. JSX is compiled by Babel into pure JavaScript. You could write your components with the base React functions, but this is slower and less readable.
127 |
128 | We want to take advantage of React to implement a declarative view that can be used to render both on the server and the browser.
129 |
130 |
131 | Any time the app state is updated, the view receives an update and displays it to the user. When the view receives user input, it notifies the app state (Redux) to make an update. The view doesn’t worry about the implementation of the business logic and app state doesn’t worry about how it will be displayed.
132 |
133 | ## React Router V4 and Universal
134 |
135 | For an isomorphic webapp, you need two things: (1) server delivers fully rendered HTML to the browser on initial load. (2) client SPA hooks itself to the HTML rendered by the server and responds to user interaction like cliking on the nav link.
136 |
137 | **TL;DR** here's what you need to do:
138 |
139 | 1. Use `StaticRoute` for server side rendering
140 | 2. Use `BrowserRoute` for client side rendering
141 | 3. Set up webpack config to make `main.js` your main entry point for your SPA
142 |
143 | I will be focusing on React Router V4 and use `react-router-config` to set up the app with routes to render both on the server side and client side.
144 |
145 | Here are some repos and docs that helped me figure out how to set up the project:
146 |
147 | * [technology-ebay-de/universal-react-router4](https://github.com/technology-ebay-de/universal-react-router4/tree/master/src/shared)
148 | * [zacfukuda/universal-app-react-router](https://github.com/zacfukuda/universal-app-react-router)
149 | * [React Router training on server rendering](https://reacttraining.com/react-router/web/guides/server-rendering)
150 | * [isomorphic-dev-js](https://github.com/isomorphic-dev-js/complete-isomorphic-example)
151 | * [EmileCantin's blog](https://blog.emilecantin.com/web/react/javascript/2017/05/16/ssr-react-router-4-webpack-code-split.html)
152 |
153 | ## Redux
154 |
155 | > [`redux`](https://redux.js.org/) is a manager of global variables for React components.
156 |
157 | ### Why we need Redux?
158 |
159 | Sometimes, we want multiple React components to render different views of the same JSON and modify that JSON. We need to have a way to properly manage global variables. [Understanding Redux](http://www.youhavetolearncomputers.com/blog/2015/9/15/a-conceptual-overview-of-redux-or-how-i-fell-in-love-with-a-javascript-state-container) explains the motivation of Redux well. Redux manages the global variables using states.
160 |
161 |
162 | Andre Staltz created a wonderful illustration of redux in action as part of his [comparison between different patterns](https://staltz.com/unidirectional-user-interface-architectures.html) for doing client side web UI using unidirectional dataflow.
163 |
164 | 
165 |
166 | From the book:
167 |
168 | 
169 |
170 | ### What is Redux
171 |
172 | Redux is based on the idea of a single root state object for the entire application, commonly referred to as the store.
173 |
174 | * **Store** - Redux holds the state of your app in its store, providing a single source of truth for your application. Redux’s store is where the state of the application lives. Redux's store is the top level (global) state of your client application and should not be confused with React component's state, which is local to the component. As the book says it:
175 |
176 | > By relying on a single root object to hold our application state, we can easily serialize our state on the server and send it down to the browser to be deserialized.
177 | * **Reducer** - Only reducers can update the store (i.e., the state of the application). Reducer makes the update by taking the current state as input and returns the next state.
178 | * **Action** - Actions trigger reducers. Actions are dispatched from the views. Actions are triggered by user actions such as a mouse click. Actions are essentially setter functions passed to React components to make changes to global states managed by redux.
179 | * **Provider** - The `Provider` provides the `store` to the React app, which allows us to connect our React components to the redux store. This is done by wrapping Provider around a top level react component called the `AppContainer`.
180 |
181 |
182 | **Store and Provider Setup**
183 |
184 | The boilerplate code for setting up redux store, provider, and reducer for an existing react app is as follows:
185 |
186 | ```javascript
187 | //AppContainer.js
188 |
189 | import React from 'react'
190 | import { applyMiddleware, compose, createStore } from 'redux'
191 | import thunk from 'redux-thunk'
192 | import promise from 'redux-promise'
193 | import createLogger from 'redux-logger'
194 | import { Provider } from 'react-redux'
195 | import AppContainer from './app/containers/AppContainer'
196 |
197 |
198 | const configureStore = (initialState) => {
199 | const logger = createLogger();
200 | const store = createStore(
201 | rootReducer,
202 | initialState,
203 | applyMiddleware(thunk, promise, logger)
204 | );
205 | }
206 |
207 | const store = configureStore(window.INITIAL_STATE);
208 |
209 | const App = () => (
210 |
211 |
212 |
213 | );
214 |
215 | export default AppContainer
216 | ```
217 |
218 | The Provider component acts as the stateful top level component. It knows when the store updates and passes that change down to its children. Individual components are also able to subscribe to the store as needed.
219 |
220 | **Reducer Setup**
221 |
222 | ```javascript
223 | /*
224 | * https://medium.com/@jonlebensold/getting-started-with-react-native-redux-2b01408c0053
225 | * Creating a reducer without using switch statements
226 | */
227 | export default function createReducer(initialState, handlers) {
228 | return function reducer(state = initialState, action) {
229 | if (handlers.hasOwnProperty(action.type)) {
230 | return handlers[action.type](state, action)
231 | } else {
232 | return state
233 | }
234 | }
235 | }
236 | ```
237 |
238 | ```javascript
239 | // reducers/todos.js
240 |
241 | import createReducer from '../lib/createReducer'
242 | import * as types from '../actions/types'
243 |
244 | export const todoCount = createReducer(0, {
245 | [types.ADD_TODO](state, action) {
246 | return state + 1;
247 | }
248 | });
249 | export const activeUsers = createReducer(init.USERS, {
250 | [types.SET_ACTIVE_USERS](state, action) {
251 | return action.state;
252 | },
253 | [types.SET_USERS](state, action) {
254 | return action.state;
255 | }
256 | });
257 | ```
258 |
259 | ```javascript
260 | // reducers/index.js
261 | import { combineReducers } from 'redux'
262 | import * as todosReducer from './todos';
263 |
264 | export default combineReducers(Object.assign(
265 | todosReducer,
266 | ));
267 |
268 | ```
269 |
270 | **AppContainer Setup**
271 |
272 | The AppContainer passes all the possible actions to the View components
273 |
274 | ```javascript
275 | //AppContainer.js
276 |
277 | import { connect } from 'react-redux'
278 | import { bindActionCreators } from 'redux'
279 | import { ActionCreators } from '../actions'
280 | import Router from '../components/Router'
281 |
282 | //Dispatching functions (boilerplate)
283 |
284 | const mapDispatchToProps = (dispatch) => {
285 | return bindActionCreators(ActionCreators, dispatch);
286 | }
287 | export default connect((state) => {
288 | //the state in the argument is the global state of the application
289 | return {
290 | todoCount: state.todoCount,
291 | username: state.username,
292 | }
293 | }, mapDispatchToProps)(Router);
294 |
295 | ```
296 |
297 | ```
298 | // Router.js
299 |
300 | const Router = () => {
301 |
302 | // ...
303 | }
304 |
305 | ```
306 |
307 | **Note**
308 |
309 | * `actions` are dispached to trigger `reducers` to change the `store`.
310 | * The components can't directly interact with the store; everything has to be done through redux:
311 | * We can retrieve data by obtaining its current state
312 | * we can change its state by dispatching an action
313 | wrapper for the top level react component referrred to as a the container.
314 |
315 |
316 |
317 | Image from [React-redux-connect explained](https://www.sohamkamani.com/blog/2017/03/31/react-redux-connect-explained/)
318 |
319 | 
320 |
321 |
322 | **Middleware for Redux**
323 |
324 | * [`redux-thunk`](https://github.com/gaearon/redux-thunk) - allows you to write action creators that return a function instead of an action. `redux-thunk` allows you to delay the dispatch of an action or to dispatch only if a certain condition is met. A thunk is a function that wraps an expression to delay its evaluation.
325 | * [`redux-promise`](https://github.com/acdlite/redux-promise) - receives a promise, dispatch the resolved value of the promise, but will not dismatch anything if the promise rejects.
326 | * [`redux-logger`](https://github.com/evgenyrodionov/redux-logger) - logging tool that lets you replay problems as if they happened in your own browser.
327 | * [`react-redux`](https://github.com/reactjs/react-redux) - We need to use `connect` from `react-redux` to connect a React component to a Redux store.
--------------------------------------------------------------------------------
/fundamental/object-oriented-programming.md:
--------------------------------------------------------------------------------
1 | ## Object Oriented Programming (OOP)
2 |
3 | The advantage of Object Oriented Programming (OOP) is that it promotes code reusability. However, poorly designed code that leverages OOP often leads to [unwieldy and untestable code](https://medium.com/@xiaoyunyang/how-to-refactor-unwieldy-untestable-code-4a73d75cb80a) that's hard to extend and test.
4 |
5 | There are two ways to do OOP:
6 |
7 | 1. Inheritance
8 | 2. Composition
9 |
10 | Composition is superior. I will explain these two concepts using Salad. Suppose you have a business that uses a self-order Kiosk to lets people order salads. They can choose between different ingredients. How would you program your kisok to let your customers pick ingredients for their salads and put in an order?
11 |
12 | ### OOP with Inheritance
13 |
14 | In the classical inheritance paradigm, you make a Salad class, which includes lettuce, a meat of your choice and a salad dressing of your choice.
15 |
16 | ```javascript
17 | function Salad() {
18 | var meat = "no meat"
19 | var dressing = "no dressing"
20 | var greens = "lettuce"
21 |
22 | var meatChoices = ["chicken", "ham", "shrimp"]
23 | var dressingChoices = ["ranch", "thousand island", "caesar"]
24 |
25 | // Getters
26 | this.getMeatChoices = function() {
27 | return meatChoices
28 | }
29 | this.getDressingChoices = function() {
30 | return dressingChoices
31 | }
32 |
33 | // Setters
34 | this.setMeat = function(choice) {
35 | meat = meatChoices[choice]
36 | }
37 | this.setDressing = function(choice) {
38 | dressing = dressingChoices[choice]
39 | }
40 | this.getOrder = function() {
41 | return {greens: greens, meat: meat, dressing: dressing}
42 | }
43 | }
44 | ```
45 |
46 | Think of configuration as picking the ingredients for your salad. Some of these ingredients can be overwritten. Some (i.e., `greens`) cannot be overwritten.
47 |
48 | ```javascript
49 | // Creates an instance of Salad
50 | var mySalad = new Salad()
51 |
52 | // Get default salad, which is only lettuce
53 | mySalad.getOrder()
54 | //> {greens: "lettuce", meat: "no meat", dressing: "no dressing"}
55 |
56 | // Add meat
57 | mySalad.getMeatChoices //> ["chicken", "ham", "shrimp"]
58 | mySalad.setMeat(0)
59 |
60 | // Add salad dressing
61 | mySalad.getDressingChoices //> ["ranch", "thousand island", "caesar"]
62 | mySalad.setDressing(2) //
63 |
64 | // Get order
65 | mySalad.getOrder()
66 | //> {greens: "lettuce", meat: "chicken", dressing: "caesar"}
67 | ```
68 |
69 | >Functions that are intended to be used with the new prefix are called constructors. By convention, they are kept in variables with a capitalized name. If a constructor is called without the new prefix, very bad things can happen without a compile-time or runtime warning, so the capitalization convention is really important. ~JavaScript: The Good Parts
70 |
71 | With this approach, you can create many different kinds of salads varying in meat and salad dressing. However, what you want to expand your salad options to include other kinds of greens like kale or spinach?
72 |
73 | The Salad object you have written comes with lettuce by default, which you **cannot override** with other greens like kale or spinach. You have to refactor your code now to make `greens` also configurable by adding a new setter function called `this.setGreens(myGreens)`, which should look a lot like the other setter functions you already have.
74 |
75 | That's an easy enough refactor. It requires your kiosks to be updated to use the new software but it's not impacting any existing functionality (other functions don't have to change).
76 |
77 | ```javascript
78 | function Salad() {
79 | // ...
80 |
81 | var greensChoices = ["lettuce", "kale", "spinach"] // <== Add this
82 |
83 | this.getGreensChoices = function() { // <== Add this
84 | return greensChoices
85 | }
86 | this.setGreens = function(choice) { // <== Add this
87 | greens = greensChoices[choice]
88 | }
89 |
90 | // ...
91 | }
92 | ```
93 |
94 | Now you want to add another ingredient to the salad: `cheese`. Your customers get only one choice of cheese, like feta, swiss, or parmesan. Adding the new ingredient is going to require more effort than making an ingredient that wasn't able to be overwritten overwritable. Not only do you have to create a setter for the cheese, you have to change your `getOrder` function to include `cheese` as part of the order.
95 |
96 | ```javascript
97 | function Salad() {
98 | var cheese = "no cheese" // <== Add this
99 | var cheeseChoices = ["feta", "swiss", "parmesan"] // <== Add this
100 |
101 | // ...
102 |
103 | this.getCheeseChoices = function() { // <== Add this
104 | return cheeseChoices
105 | }
106 | this.setCheese = function(choice) { // <== Add this
107 | greens = cheeseChoices(choice)
108 | }
109 |
110 | // ...
111 |
112 | this.getOrder = function() { // <== Change this
113 | return {greens: greens, meat: meat, dressing: dressing, cheese: cheese}
114 | }
115 | }
116 | ```
117 |
118 | As your salad business grows, your customer demands more choices and customizability to their salads, you keep adding things to and changing things in `Salad`. You also want to make special ingredients only available on certain day of the week or holidays so you are adding `Date` to your code so you can display
119 |
120 | and offer your customers the option to skip all the customization and go straight to menu items like greek salad or caesar salad. Before you know it, your `Salad` code starts to becomes riddled with conditionals, non-deterministic behavior tightly coupled with the environment in which it runs. It's difficult to unit test because you have to simulate the environment that produces certain results. For example, you decided to add `Date` logic to your `getMeatChoices` function so it will only display "shrimp" on Tuesdays. This means your `Salad` function will literally give you different results when you run it at different times. This is the definition of non-determinism. Further, you can't immediately tell if your added functionality is going to break existing functionality without acceptance testing (i.e., load the new code into a kiosk and click on buttons to see what happens). In the example, you have to wait until Tuesday to see if your `getMeatChoices` returns "shrimp" as an option if you don't have a test suite that can simulate time, or other environmental variables.
121 |
122 | There's stuff you can do like refactoring your code everytime you add functionality to it that you think will make it become untestable. But refactoring takes time and effort. You are running a busy salad shop by yourself so you don't have the time to do it yourself and you don't make enough money to hire a developer after paying your kitchen staff, rent, and taxes. This is not a good situation to be in.
123 |
124 | Let's rewind and see how we can design our `Salad` code differently so we won't run into these problems.
125 |
126 |
127 | ### OOP with Composition
128 |
129 | JavaScript is a prototypal inheritance language. That means that objects can inherit properties directly from other objects. The language is class-free.
130 |
131 | When a function is stored as a property of an object, we call it a method. When a method is invoked, this is bound to that object. If an invocation expression contains a refinement (that is, a . dot expression or [subscript] expression), it is invoked as a method:
132 |
133 | ```javascript
134 | var salad = {
135 | meat: "no meat",
136 | dressing: "no dressing",
137 | greens: "lettuce",
138 | getOrder: function() {
139 | return {greens: this.greens, meat: this.meat, dressing: this.dressing}
140 | },
141 | };
142 | ```
143 |
144 | ```javascript
145 | var meatChoices = ["chicken", "ham", "shrimp"]
146 | var dressingChoices = ["ranch", "thousand island", "caesar"]
147 | ```
148 |
149 | **Prototype** lets you create new object using old object as prototype:
150 |
151 | ```javascript
152 | var caesarSalad = Object.create(salad)
153 | ```
154 |
155 | You can think about the prototype as the default object. If we try to retrieve a property value from an object, and if the object lacks the property name, then JavaScript attempts to retrieve the property value from the prototype object.
156 |
157 | ```javascript
158 | caesarSalad.getOrder()
159 | //> {greens: "lettuce", meat: "no meat", dressing: "no dressing"}
160 |
161 | caesarSalad.meat = "chicken"
162 | caesarSalad.dressing = "caesar"
163 | caesarSalad.getOrder()
164 | //> {greens: "lettuce", meat: "chicken", dressing: "caesar"}
165 | ```
166 |
167 | We can augment the salad object with cheese.
168 |
169 | ```javascript
170 | salad.cheese = "no cheese"
171 | salad.getOrder = function() {
172 | return {
173 | greens: this.greens,
174 | meat: this.meat,
175 | dressing: this.dressing,
176 | cheese: this.cheese
177 | }
178 | }
179 | ```
180 |
181 | The prototype relationship is a dynamic relationship. If we add a new property to a prototype, that property will immediately be visible in all of the objects that are based on that prototype:
182 |
183 | ```javascript
184 | caesarSalad.getOrder()
185 | {greens: "lettuce", meat: "chicken", dressing: "caesar", cheese: "no cheese"}
186 | ```
187 |
188 | Because we specified a value for `meat` in the new object, it overwrites the prototype object's value for `meat`. We didn't specify anything for `cheese` for the new old object, so the default "no cheese" from the prototype object was inherited.
189 |
190 | We can also delete the specifity in the new object to see that the value reverts back to the prototype's value:
191 |
192 | ```javascript
193 | delete caesarSalad.meat //> true
194 | caesarSalad.meat //> "no meat"
195 | ```
196 |
197 |
198 | A method can use this to access the object so that it can retrieve values from the object or modify the object. The binding of this to the object happens at invocation time. This very late binding makes functions that use this highly reusable. Methods that get their object context from this are called public methods.
199 |
200 |
201 | ```javascript
202 | // Augment stooge object with an ageUp method.
203 | stooge.ageUp = function() {
204 | var that = this;
205 | var helper = function() {
206 | that.age = that.age+1
207 | }
208 | helper();
209 | }
210 |
211 | // Augment stooge object with a displayAge method.
212 | stooge.displayAge = function() { return this.age }
213 |
214 |
215 | stooge.displayAge() //> 37
216 | stooge.ageUp()
217 | stooge.displayAge() //> 38
218 | ```
219 | **Prototype** lets you create new object using old object as prototype:
220 |
221 | ```javascript
222 | var anotherStooge = Object.create(stooge)
223 | anotherStooge.first_name //> "Jerome"
224 | anotherStooge.first_name = "Harry"
225 | anotherStooge.first_name //> "Harry
226 | ```
227 |
228 |
229 |
230 |
231 | ```javascript
232 | stooge.profession = "actor"
233 | anotherStooge.profession //> "actor"
234 | ```
235 | We can also delete:
236 |
237 | ```javascript
238 | delete anotherStooge.first_name //> true
239 | anotherStooge.first_name //> "Jerome"
240 | ```
241 |
242 | ## Read
243 | * [ ] Classes in ES6 [official doc](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)
--------------------------------------------------------------------------------
/fundamental/scoping-and-closure-in-javascript.md:
--------------------------------------------------------------------------------
1 | ## The JavaScript Closure
2 | ### What is Closure?
3 |
4 | [One definition](https://medium.freecodecamp.org/lets-learn-javascript-closures-66feb44f6a44) is this:
5 | > Closures are functions that refer to independent (free) variables. In other words, the function defined in the closure ‘remembers’ the environment in which it was created.
6 |
7 | [Another definition](https://medium.freecodecamp.org/3-questions-to-watch-out-for-in-a-javascript-interview-725012834ccb)
8 | > A closure is basically when an inner function has access to variables outside of its scope. Closures can be used for things like [implementing privacy](https://medium.com/written-in-code/practical-uses-for-closures-c65640ae7304) and creating [function factories](https://medium.com/javascript-scene/javascript-factory-functions-vs-constructor-functions-vs-classes-2f22ceddf33e#.1817w0lmb).
9 |
10 | I like this definition from [Secrets of the JavaScript Ninja](https://www.manning.com/books/secrets-of-the-javascript-ninja-second-edition) better:
11 | >A closure is a way to access and manipulate external variables from within a function.
12 |
13 |
14 |
15 | ### Closure in action:
16 |
17 | Closure can let you do some cool things, like object oriented programming in JavaScript:
18 |
19 | ```javascript
20 | function Person(name) {
21 |
22 | var secret = "secret!"
23 | this.name = name
24 |
25 | this.setName = function(newName) { this.name = newName }
26 | this.setNameToFoo = function() { this.name = foo }
27 | this.getSecret = function() { return secret }
28 | }
29 |
30 | var a = new Person("Max")
31 |
32 | a.name //> "Max"
33 | a.setName("Oliver")
34 | a.name //> "Oliver"
35 | a.setNameToFoo() //> ERROR: foo is undefined
36 |
37 | var foo = "Foo"
38 | a.setNameToFoo()
39 | a.name //> "Foo"
40 |
41 | a.secret //> undefined
42 | a.getSecret() //> "Secret!"
43 | ```
44 |
45 | And recursion:
46 |
47 |
48 | ```javascript
49 | var incrementUntil = function(max) {
50 | if(num >= max)
51 | return num
52 |
53 | num++
54 | incrementUntil(max)
55 | }
56 |
57 | var num = 0
58 | incrementUntil(3)
59 | num //> 3
60 |
61 | ```
62 |
63 | Let's try a couple of things based on the function we created in the recursion example:
64 |
65 | ```javascript
66 | num = 0
67 | var myFun = function() {
68 | incrementUntil(3)
69 | return num
70 | }
71 | myFun() //> 3
72 | num //> 3
73 | ```
74 |
75 | So far so good...
76 |
77 | ```javascript
78 | num = 0
79 | var myFun2 = function() {
80 | var num = -1
81 | incrementUntil(3)
82 | return num
83 | }
84 | myFun2() //> -1 .......Why?
85 | num //> 3
86 |
87 | ```
88 |
89 | ...Uh oh what happened?
90 |
91 |
92 | **Some Observations:**
93 |
94 | * `incrementUntil` can call itself because it maintains a closured reference to itself. This makes recursion possible in JavaScript.
95 | * `incrementUntil` also maintains a closured reference to `num` and can read and modify it. The scope of `num` is `window` if you typed this example as-is directly into the browser console.
96 | * Although `incrementUntil` is being executed inside of `myFun2`, it didn't modify the `num` in `myFun2`'s scope because `incrementUntil` only recognizes the `num` that was inside of its parent's scope when it was first created (e.g., `window`). It doesn't recognize the `num` inside of the caller, `myFun2`, because it doesn't maintain a closured reference to its caller's scope.
97 |
98 |
99 | Here's how we can fix `myFun2` so it can leverage the `incrementUntil` function to modify the `num` inside of its own scope.
100 |
101 | ```javascript
102 | var myFun2 = function() {
103 | var num = -1
104 |
105 | function incrementUntil(max) {
106 | if(num >= max)
107 | return num
108 | num++
109 | incrementUntil(max)
110 | }
111 | incrementUntil(3)
112 |
113 | return num
114 | }
115 |
116 | myFun2() //> 3
117 | ```
118 |
119 |
120 | The "fix" for `myFun2` seems to work fine but it lends itself to a lot of duplicate code. What if we have to increment variables inside of other functions? It's not good practice to copy-paste the same function/code into multiple places. Let's refactor our `incrementUntil` function using **partial application**:
121 |
122 | ```javascript
123 | var incrementUntil = function(max) {
124 | var inc = function(num) {
125 | if(num >= max) return num
126 | return inc(num+1)
127 | }
128 | return (num) => inc(num)
129 | }
130 |
131 | incrementUntil(4)(1) //> 4
132 | incrementUntil(8)(3) //> 8
133 |
134 | var num = 1
135 | incrementUntil(8)(num) //> 8
136 | num //> 1 .... Good! Our function is pure!
137 | ```
138 |
139 | The refactored `incrementUntil` function does not read or modify anything outside of its own scope so it's a pure function, which illustrates a core principle of functional programming. You call the function as follows: `incrementUntil(max)(num)`, which reads "increment until `max` starting from `num`".
140 |
141 | A really nice thing about partial application is that we can partially evaluate the final solution by providing our function one of the arguments it needs. Then we can save the intermediate solution to a variable so we can save ourselves some processing time by eliminating the need to evaluate the same intermediate solution every time we call the function to do similar things. Here's what I mean by that in code:
142 |
143 | ```javascript
144 | var multThenAdd = mul => {
145 | return add => num => {
146 | return num * mul + add
147 | }
148 | }
149 |
150 | var timesTwoPlusFour = multThenAdd(2)(4)
151 |
152 | timesTwoPlusFour(1) //> 6
153 | timesTwoPlusFour(10) //> 24
154 | ```
155 |
156 | Now you've seen partial application in action, here's a high level discussion on the concept of partial application (also called currying by some).
157 |
158 | Partial application is basically a design pattern where your function returns another function that takes an argument.
so you can call your function like this: `myFun(arg1)(arg2)`, which is equivalent to
159 |
160 | ```
161 | const myFun2 = myFun(arg1)
myFun2(arg2)
```
162 |
163 | Partial application is a powerful design pattern because you can continuing chaining things like `myFun(arg1)(arg2)(arg3)…` myFun partially applies `arg1`, returns another function that takes `arg2` as argument and applies `arg2` to the result of `myFun` evaluated over `arg1`. So on and so forth.
164 |
165 | Partial application is a powerful design pattern because you can continuing chaining things like `myFun(arg1)(arg2)(arg3)…`. What’s happening here is akin to an assembly line in a factory: One argument at a time is applied to myFun to evaluate a better and better partial solution until all the arguments are applied to provide a complete solution.
166 |
167 | Here's an actual piece of code I wrote for a Node/Express app:
168 |
169 | ```javascript
170 | const getInfoFromURL = path => {
171 | const URL = require("url").URL;
172 | const myUrl = new URL(path)
173 | const pathname = myUrl.pathname
174 |
175 | const getUsernameFromURL = pathname => {
176 | const regex = new RegExp('/@');
177 | const username = pathname.split(regex).slice(1)[0]
178 | if(!username) {
179 | return "Error in parsing: URL needs to be in format://hostname:port/@username"
180 | }
181 | return username
182 | }
183 | const getPathnameFromURL = pathname => {
184 | const regex = new RegExp('/');
185 | const name = pathname.split(regex).slice(1)[0]
186 | if(!name) {
187 | return "Error in parsing: URL needs to be in format://hostname:port/pathname"
188 | }
189 | return name
190 | }
191 |
192 | return (param) => {
193 | if (param === "username") return getUsernameFromURL(pathname)
194 | else if (param === "pathname") return getPathnameFromURL(pathname)
195 | else return "error"
196 | }
197 | }
198 |
199 | module.exports = getInfoFromURL
200 |
201 | ```
202 | How you call the above code?
203 |
204 | ```javascript
205 | // You should get "xiaoyunyang"
206 | getInfoFromURL("https://medium.com/@xiaoyunyang")("username")
207 | // You should get "@xiaoyunyang
208 | getInfoFromURL(path)("pathname")
209 | ```
210 |
211 |
212 | ## Closure Under The Hood
213 |
214 | For background, read [the primer on execution context in JavaScript](http://davidshariff.com/blog/what-is-the-execution-context-in-javascript/)
215 |
216 | [This article](https://medium.com/dailyjs/i-never-understood-javascript-closures-9663703368e8) explains it well:
217 |
218 | >One intricacy of JavaScript is how it looks for variables. If it can’t find a variable in its local execution context, it will look for it in its calling context. And if not found there in its calling context.
219 |
220 |
221 | > When we start the program, we start in the global execution context. Some variables are declared within the global execution context. We call these global variables. When the program calls a function, what happens? A few steps:
222 |
223 | > 1. JavaScript creates a new execution context, a local execution context
224 | 2. That local execution context will have its own set of variables, these variables will be local to that execution context.
225 | 2. The new execution context is thrown onto the execution stack. Think of the execution stack as a mechanism to keep track of where the program is in its execution
226 |
227 | If you came from a C or embedded systems background, this should be very familiar. The "global execution context" is like the main operating loop, which contains many subroutines (i.e., helper functions. The "local execution context" is like the stack frame that's created whenever the subroutine starts executing; however, instead of pushing the stack frame onto the [call stack](https://www.wikiwand.com/en/Call_stack), JavaScript pushes it into the heap. Storing local execution context of a function on the call stack makes the context lost after the function finishes executing. Storing the local execution context in the heap allows your local execution context (i.e., function) to stay alive after it finishes executing. All you need to access that local execution context is a reference to the subroutine.
228 |
229 | Languages which support closure (such as JavaScript, Swift and Ruby) will allow you to keep a reference to a scope (including its parent scopes), even after the block in which those variables were declared has finished executing, provided you keep a reference to that block or function somewhere.
230 |
231 | Another way of thinking about this is a closure is a persistent scope which holds on to local variables even after the code execution has moved out of that block. The scope object, and all its local variables, are tied to the function, and will persist as long as that function persists.
232 |
233 | Closure captures any variables that were in scope when the function was first defined and make these variables available when we later call the function, even if we call the function in a completely different context. Note, the closure captures not the value of the variable nor the value of the reference the variable points to, but the variable itself!
234 |
235 |
236 | **Resources**
237 | * [I Never Understood JavaScript Closures](https://medium.com/dailyjs/i-never-understood-javascript-closures-9663703368e8) 😍
238 | * [Everything You Need to Know about Scopes](https://toddmotto.com/everything-you-wanted-to-know-about-javascript-scope/) - which discusses closure.
239 | * [Secrets of the JavaScript Ninja](https://www.manning.com/books/secrets-of-the-javascript-ninja-second-edition)
240 | * [Making Functional Programming Click](https://hackernoon.com/making-functional-programming-click-836d4715baf2)
241 | * [MDN Closure Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)
242 | * [Tricky Closure Inteview Question](https://medium.com/coderbyte/a-tricky-javascript-interview-question-asked-by-google-and-amazon-48d212890703)
243 | * [JavaScript Closure Questions](https://coderbyte.com/algorithm/3-common-javascript-closure-questions)
244 | * [Three Questions to watch out for in JavaScript Interview](https://medium.freecodecamp.org/3-questions-to-watch-out-for-in-a-javascript-interview-725012834ccb)
245 | * [JS Scope](https://www.w3schools.com/js/js_scope.asp)
246 | * [Scotch.io's scope, closure, and context tutorial](https://scotch.io/tutorials/understanding-scope-in-javascript) 😍
247 |
248 | ### Tricky Questions on Closure and Scoping in JS
249 |
250 | 1. What will this output?
251 |
252 | ```javascript
253 | for (var i = 0; i < 3; i++) {
254 | setTimeout(function() { console.log(i); }, 1000 + i);
255 | }
256 | ```
257 | [Solution](https://coderbyte.com/algorithm/3-common-javascript-closure-questions)
258 |
259 | 2. What will this output?
260 |
261 | ```javascript
262 | const arr = [10, 12, 15, 21];
263 | for (var i = 0; i < arr.length; i++) {
264 | setTimeout(function() {
265 | console.log('Index: ' + i + ', element: ' + arr[i]);
266 | }, 3000);
267 | }
268 | ```
269 | [Solution](https://medium.com/coderbyte/a-tricky-javascript-interview-question-asked-by-google-and-amazon-48d212890703)
270 |
271 | 3. Write a function that would allow you to do this.
272 |
273 | ```javascript
274 | var addSix = createBase(6);
275 | addSix(10); // returns 16
276 | addSix(21); // returns 27
277 | ```
278 |
279 | Solution:
280 |
281 | ```javascript
282 | var createBase = (base) => (num) => base + num
283 | var addSix = createBase(6)
284 | addSix(10) //> 16
285 | addSix(21) //> 21
286 | ```
287 |
288 | ### Gotchas
289 | **Scope vs. context**
290 |
291 | While scope refers to the visibility of variables from different parts of your code, context refers to the use of `this` keyword in your code.
292 |
293 | What is `this`?
294 |
295 | ```javascript
296 | var fun = function() {
297 | var name = "Max"
298 | return this
299 | }
300 | fun() //> Window { postMessage: f, blur ..... }
301 | fun().name //> undefined
302 | ```
303 |
304 | Why was `fun().name` undefined? Well because it's `var` and is private to the function `fun`. Being private means you can't access it from the outside.
305 |
306 | You can access `name` if you made this change:
307 |
308 | ```javascript
309 | var fun = function() {
310 | this.name = "Max"
311 | return this
312 | }
313 | fun().name //> "Max"
314 | ```
315 |
316 | Why does the above code work? When we are assigning a value to `this.name`, we are creating a variable called `name` inside the context of the function `fun`.
317 |
318 | Or if you made this change:
319 |
320 | ```javascript
321 | var fun = function() {
322 | var name = "Max"
323 | return {this: this, name: name}
324 | }
325 | fun().this //> Window { postMessage: f, blur ..... }
326 | fun().name //> "Max"
327 | ```
328 |
329 | When we called `fun()` in the code above, the context for `fun` was returned. This is what `fun`'s `this` gives you:
330 |
331 | ```
332 | Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
333 | ```
334 |
335 | But the context of `fun` is the context of `Window`! This can be proven with a simple test:
336 |
337 | ```javascript
338 | fun().this === this //> true
339 | ```
340 |
341 | Here's where it gets confusing with ES6. ES6 let's you create an arrow function, which works like a function but is not a `function`. So before you start changing all your `function` to `=>`, beware that doing this could break your code.
342 | mbeaudru provided [this great summary](https://github.com/mbeaudru/modern-js-cheatsheet#this-reference);
343 | >An arrow function doesn't create a new `this`, it grabs it from its surrounding instead. Let's refactor the code above to create an arrow function and see what happens:
344 |
345 |
346 | ```javascript
347 | var fun = function() {
348 | var name = "foo"
349 | var innerFun = function() {
350 | var name = "bar"
351 | return {this: this, name: this.name}
352 | }
353 | return innerFun()
354 | }
355 |
356 | fun() //> {this: Window, name: "bar"}
357 | fun().this === this
358 | ```
359 | The `this` of the `innerFun` is still `Window`. That hasn't changed.
360 |
361 | ```javascript
362 | var fun = function() {
363 | this.name = "foo"
364 | var innerFun = function() {
365 | var name = "bar"
366 | return {fun: "inner", this: this, name: name}
367 | }
368 | return [innerFun(), {fun: "outer", this: this, name: this.name}]
369 | }
370 |
371 | fun()[0] //> {fun: "inner", this: Window, name: "bar"}
372 | fun()[1] //> {fun: "outer", this: Window, name: "foo"}
373 | ```
374 |
375 | If you removed the name `var` in front of the `name` in the inner function, you'll get different answers
376 |
377 | ```javascript
378 | var fun = function() {
379 | this.name = "foo"
380 | var innerFun = function() {
381 | name = "bar"
382 | return {fun: "inner", this: this, name: name}
383 | }
384 | return [innerFun(), {fun: "outer", this: this, name: this.name}]
385 | }
386 |
387 | fun()[0] //> {fun: "inner", this: Window, name: "bar"}
388 | fun()[1] //> {fun: "outer", this: Window, name: "bar"}
389 | ```
390 |
391 | ## JavaScript and Context
392 |
393 | [Why and how to bind methods](http://reactkungfu.com/2015/07/why-and-how-to-bind-methods-in-your-react-component-classes/)
394 | >In languages like Ruby or Java, this (or in case of Ruby self) will always point to the object in which your method is defined. So in Ruby if you are working on the foo method inside the Bar class, self will always point to the object which is the instance of the Bar class.
395 |
396 | >JavaScript works quite surprisingly here. Because in JavaScript function context is defined while calling the function, not while defining it! This is what can surprise many when coming to JS from different fields. Such late binding is a powerful mechanism which allows us to re-use loosely coupled functions in variety of contexts.
397 |
398 |
399 | ### Bind
400 |
401 | > Bounded function in JavaScript is a function that is bounded to a given context. That means no matter how you call it, the context of the call will stay the same. The only exception is the new operator which always return a new context.
402 |
403 |
404 | ```javascript
405 | function add(x, y) {
406 | this.result += x + y;
407 | return this.result;
408 | }
409 |
410 | var computation1 = { result: 0 };
411 | var boundedAdd = add.bind(computation1);
412 |
413 | boundedAdd(-1,-2) //> -3
414 | boundedAdd(-1,-2) //> -6
415 |
416 | // Change context
417 | computation1 = { result: 12 };
418 | boundedAdd = add.bind(computation1);
419 | boundedAdd(-1,-2) //> 9
420 | ```
421 |
422 | ### Class
423 |
424 | > ECMAScript 2015 (ECMAScript 6) introduced a new class syntax that can be used to create React component classes. In fact, this class syntax is a syntactic sugar for the old, prototype system of object-oriented JavaScript.
425 |
426 | ```javascript
427 | class Foo {
428 | constructor() {
429 | this.x = 2;
430 | this.y = 4;
431 | }
432 |
433 | bar() {
434 | // ...
435 | }
436 |
437 | baz() {
438 | // ...
439 | }
440 | }
441 | ```
442 |
443 | Is roughly the same as:
444 |
445 | ```javascript
446 | function Foo() {
447 | this.x = 2;
448 | this.y = 4;
449 |
450 | this.bar = function() { // ... };
451 | this.baz = function() { // ... };
452 | }
453 | ```
--------------------------------------------------------------------------------
/fundamental/tech-behind-modern-webapps.md:
--------------------------------------------------------------------------------
1 | # Understanding Web Technology
2 |
3 | ## Motivation
4 |
5 | This is an introduction of concepts and technology behind modern web applications. Modern web applications are built on stacks of open source libraries and frameworks. You can visit [stackshare.io](https://stackshare.io/airbnb/airbnb) to see the stacks used by tech companies such as Airbnb.
6 |
7 |
8 | ## Front End
9 | In the early days of the Internet, everyone writes their websites in HTML. The Document Object Model (DOM) is a programming API for HTML. The object model itself closely resembles the structure of the documents it models. For instance:
10 |
11 | ```
12 |
A List:
13 |
A List
14 |
One
15 |
Two
16 |
17 | ```
18 |
19 | gives you
20 | >
A List:
One
Two
21 |
22 | When you visit a website built in the 1990s, your browser (e.g., Chrome, Firefox, Safari) makes a request to the server of the website to download all files it needs to display the webpage. For instance, the HTML file tells your browser how to create a DOM. The Cascading Style Sheets (CSS) file tells your browser how to apply styles, such as text color and font, to the DOM. Go ahead and open [https://www.w3.org/TR/WD-DOM/introduction.html](https://www.w3.org/TR/WD-DOM/introduction.html) with Chrome and press `Cmd + Shift + C` to inspect the DOM. Press `Cmd + s` to save the webpage to your computer and click the `.html` file stored on your computer to see that the same webpage is displayed.
23 |
24 | Static webpages are undesirable from a user perspective as well as from a web developer perspective. Users cannot interact much with a static website other than viewing the content. The owner of the website has to modify the html file to change the content of page.
25 |
26 | Javascript frameworks provide a way for the client (i.e., the browser) to manipulate the DOM. The client may interact with DOM in different ways (e.g., collapsing and filtering a list). Javascript frameworks also handle the interface between the DOM and server. There are [many javascript frameworks](https://hackernoon.com/5-best-javascript-frameworks-in-2017-7a63b3870282) out there but none is more powerful than [React](https://reactjs.org/docs/thinking-in-react.html).
27 |
28 |
29 | ### React
30 | >React is a declarative, efficient, and flexible JavaScript library for building user interfaces.
31 |
32 | **[`React`](https://reactjs.org/tutorial/tutorial.html)** is a Javascript library, built and maintained by Facebook. It was developed by [Jordan Walke](https://twitter.com/jordwalke), a software engineer at Facebook. It was open-sourced and announced to the developer community in May 2013. Since then, it has undergone tremendous growth and adoption in the developer community. React is currently on version 16 (See the [Migration log](https://reactjs.org/blog/2017/04/07/react-v15.5.0.html#migrating-from-react.proptypes) to appreciate the pace of growth in popularity and capability of React).
33 |
34 | React gives the developer full control of the DOM and covers the rendering of initial state and updating the state to reflect changes based on user or server input.
35 |
36 | * [Good Introduction to React from Auth0](https://auth0.com/blog/reactjs-authentication-tutorial/)
37 | > React lets you create custom and reusable HTML elements. React provides some methods that are triggered at various points from creating a component up until the component is destroyed. This is called the Component's Lifecycle. You can declare methods to hook into the component's lifecycle to control the behavior of components in your app. Some examples of these lifecycle hooks are `componentDidMount()`, `componentWillMount()`, `componentWillUnmount()`, `shouldComponentUpdate()`, `componentWillUpdate()` and more. Read more about the lifecycle API [here](http://www.react.express/lifecycle_api)
38 |
39 | What is a `prop`?
40 |
41 | > Props is the short form for properties. Properties are attributes of a component. In fact, props are how components talk to each other. A tag in HTML such as `` has an attribute, a.k.a prop called src that points to the location of an image.
42 |
43 | In React, application data flows unidirectionally via the state and props objects, as opposed to the [data binding](https://www.themarketingtechnologist.co/introduction-to-data-binding-in-angular-2-versus-angular-1/) of libraries like [Angular](https://angular.io/) (another popular Javascript framework for building web apps). This means that, in a multi-component hierachy, a common parent component should manage the state and pass it down the chain via the `prop`.
44 |
45 |
46 | * [Thinking in React](https://reactjs.org/docs/thinking-in-react.html)
47 |
48 | > Since you’re often displaying a JSON data model to a user, you’ll find that if your model was built correctly, your UI (and therefore your component structure) will map nicely. That’s because UI and data models tend to adhere to the same information architecture, which means the work of separating your UI into components is often trivial.
49 |
50 | For example, when you first click on the link to visit [KhanAcademy](https://www.khanacademy.org/)'s home page -- a webpage built on React -- your browser makes a request to the KhanAcademy's server to load the React code. The browser executes the React code, which creates React components. Each React component generates the part of the DOM it is responsible for by making another (asynchronous) request to the webpage's server or another server's API (more on that later) to grab the data (typically JSON) it needs to generates the appropriate information that needs to be displayed on the webpage. For subsequent updates to the webpage, the React component repeats the steps to load JSON from the server or API and updates the information on the webpage.
51 |
52 | [matthias nehlsen's blog](http://matthiasnehlsen.com/blog/2014/01/05/play-framework-and-facebooks-react-library/):
53 | >
54 | * *
55 | * Components can have state if necessary.
56 | * React prefers immutable props over mutable state wherever possible, making state changes much easier to reason about.
57 | * Each component knows how to render itself.
58 | * Components can have other components as children. They can pass their own state or props to these as immutable props.
59 | * The entire DOM is rendered into a (fast) virtual DOM with every change made. Changes can either come from mutated state or from parent elements as immutable props.
60 | * This virtual DOM is then diffed against a representation of the current DOM, with the actual DOM only being manipulated where new and old versions differ.
61 | * Data coming from business logic outside will not be touched; React can work withimmutable data thoughout.
62 | * Hierarchical components, props, state, handlers. That’s pretty much it, no more rather unintuitive concepts to understand.
63 |
64 |
65 | ### Redux
66 |
67 |
68 | ## Building an API
69 |
70 | ### RESTful API
71 | > The RESTful API provides a way for the frontend app to talk to a server.
72 |
73 | **Why we need a RESTful API?**
74 |
75 | The motivation for a RESTful API is to promote separation of concerns between the frontend application (the client) and the backend application (the server). REST, which stands for Representational State Transfer) provides an communications interface between the client and the server so that the client does not need to be concerned with data storage, which remains internal to the server, and the server does not need to be concerned with the display and user manipulation of the DOM, which remains internal to the client.
76 |
77 | Separation of concerns improves portability of both the client code and server code. To support this goal, we need a way for the client to talk to server. The most common communications between a client and a server are the `GET` and `PUT`. The client asks the server for information via a HTTP `GET` requests and displays a DOM to the user based on that information. The client also gives the server information based on user input via a HTTP `PUT`. The information that's passed back and forth is in a format called JSON, which looks something like this: [https://api.github.com/users/xiaoyunyang/repos](https://api.github.com/users/xiaoyunyang/repos)
78 |
79 | While we (people) can view the JSON via clicking on the link and opening it up in the browser, the frontend app can view this data via making the following HTTP request:
80 |
81 | ```
82 | GET https://api.github.com/users/xiaoyunyang/repos
83 | ```
84 |
85 | which can be generalized as follows:
86 |
87 | ```
88 |
89 | ```
90 |
91 | **Endpoint** is the address (i.e., a URL) of the service. We will discuss HTTP in the section below.
92 |
93 | The above example is supported by the [Github API](https://developer.github.com/v3/repos/#list-your-repositories). Many websites that collect a lot of data from their users provide an API that allows web developers to access that data. Some good APIs include:
94 |
95 | * [Twitter API](https://developer.twitter.com/en/docs/tweets/post-and-engage/overview) - Grab tweets (useful for news websites)
96 | * [Github API](https://developer.github.com/v3/repos/#list-your-repositories) - Grab repo information (useful if you are making an app to compare the popularity of open source libraries in real time)
97 | * [Facebook Graph API](https://developers.facebook.com/docs/graph-api/) - Get user profile info or business info
98 | * [Yelp Fusion API](https://www.yelp.com/developers/documentation/v3/business_search) - Find Information about businesses
99 |
100 | The above example demonstrates the another usefulness of REST API as it allows you to build frontend applications that can talk to not just its own server, but other servers that provides public access to their data via a REST API.
101 |
102 | **What is HTTP?**
103 |
104 | [HTTP](https://www.wikiwand.com/en/Hypertext_Transfer_Protocol) stands for Hypertext Transport Protocol. It was invented for the Web to retrieve HTML, images, documents etc. The basic concept of HTTP is (1) establish a connection, (2) request a document, (3) retrieve the document, and (4) close the connection. Let's see HTTP in action. In your terminal, type:
105 |
106 | ```
107 | $ telnet www.rigaut.com 80
108 | ```
109 | Port 80 is the non-encrypted HTTP port. If you see the following, the connection went through:
110 |
111 | ```
112 | Trying 80.248.208.218...
113 | Connected to www.rigaut.com.
114 | Escape character is '^]'.
115 | ```
116 |
117 | Then type:
118 | ```
119 | GET /benoit/CERN/about/
120 | ```
121 | get the following response:
122 |
123 | ```
124 |
125 | ...
126 |
127 | Connection closed by foreign host.
128 | ```
129 | That's essentially what your browser does when you visit [http://www.rigaut.com/benoit/CERN/about](http://www.rigaut.com/benoit/CERN/about/). Your browser gets back a bunch of HTML and it will render a DOM based on the HTML and displays the webpage to you. A browser is a software application that makes HTTP requests, processes the HTTP response (e.g., HTML), and display that to you.
130 |
131 | **HTTP Requests**
132 |
133 | As stated above, REST is based on HTTP. We need to have a way to respond to a request with a message when the response is success or has an error.
134 |
135 | These are all the [HTTP requests](http://www.restapitutorial.com/lessons/httpmethods.html), their corresponding operation, and response in HTTP status codes:
136 |
137 | | HTTP Verb | CRUD Operation | Response (status Codes) |
138 | | :--------: |:---------------------:|:------------------------|
139 | | `POST` | Create | 201, 404, 409 |
140 | | `GET` | Read | 200, 304, 404 |
141 | | `PUT` | Update/Replace/Create | 200, 201, 204, 404, 405 |
142 | | `PATCH` | Update/Modify | 200, 204, 404, 405 |
143 | | `DELETE` | Delete | 200, 204, 404, 405 |
144 |
145 |
146 |
147 | These are the typical [HTTP status codes](https://www.wikiwand.com/en/List_of_HTTP_status_codes), their definition, and an easy way to remember the ranges per [the tweet from @stevelosh](https://twitter.com/stevelosh/status/372740571749572610):
148 |
149 | **The 200 range**
150 | > Here you go
151 |
152 | * `200`= OK
153 | * The `GET` request has succeeded and content was retrieved.
154 | * `201` = Created
155 | * This status is provided as response to a successful `POST` (or if using`PUT` for create) request along with a location header with a link to the newly-created resource.
156 | * `204` = No content
157 | * A response to a `PUT` or `PATCH` request upon successful update if not returning any content in the body. In the case of `DELETE`, you return `204` after a successful delete operation.
158 |
159 | **The 300 range**
160 | > Go away
161 |
162 | * `301`= Moved Permanently
163 | * The requested resource has been assigned a new permanent URI and any future references to this resource should use one of the returned URIs.
164 | * `303` = See Other
165 | * Resource is already created and you want to redirect to a new page.
166 | * `304` = A successful response to `GET`. Resource is still fetched for the browser, but as opposed to `200` where a new thing is fetched, a `304` status means the resource for current fetch request matches that of a previous fetch request so there is no need to retransmit the resource since the client still has a previously-downloaded copy.
167 |
168 | **The 400 range**
169 | > You messed up
170 |
171 | * `400`= Bad Request
172 | * The request could not be understood by the server due to malformed syntax. The client should not repeat the request without modifications.
173 | * `401`= Unauthorized
174 | * The request requires user authentication.
175 | * `403` = Forbidden
176 | * Even logged in user has no permission to do something. For example, if logged in user can access some parts of the static files but not others.
177 | * `404`= Not Found
178 | * For example, a `GET` request on something that cannot be fetched because there is no code matched to the URI. a `DELETE` request on something with an ID not found or invalid.
179 | * `405` = Method Not Allowed
180 | * For example, a `GET` request on a form that requires data to be presented via `POST`, or a `PUT` request on a read-only resource.
181 | * `409` = Conflict
182 | * A response to a failed `POST` request (e.g., cannot create user because user already exists).
183 |
184 | **The 500 range**
185 | > I messed up
186 |
187 | * `500` = Internal Server Error
188 | * In an express app, the 500 error is associated with a requesting a file that does not exist. For example, if you are using `res.sendFile` to send an nonexisting file.
189 | * Unlike the rest of the status codes where you want to be as descriptive as possible, it’s often better to be vague and say “Internal Server Error”; that way hackers can’t know where the weaknesses in your system lie.
190 | * `503`= Service Unavilable
191 |
192 | See more [from the DigitalOcean Tutorial](https://www.digitalocean.com/community/tutorials/how-to-troubleshoot-common-http-error-codes)
193 |
194 | ### GraphQL
195 | [REST vs GraphQL](https://blog.pusher.com/rest-versus-graphql/)
196 | > GraphQL is a declarative data fetching specification and query language for APIs. It was created by Facebook back in 2012 to power their mobile applications. It is meant to provide a common interface between the client and the server for data fetching and manipulations. GraphQL was open sourced by Facebook in 2015.
197 |
198 | > REST and GraphQL can both be operated over HTTP, though GraphQL is protocol agnostic.
199 |
200 | In 2016 [Github migrated its API from REST to GraphQL](https://developer.github.com/v4/guides/intro-to-graphql/)
201 |
202 | [Apollo's Article](https://dev-blog.apollodata.com/graphql-vs-rest-5d425123e34b) on two ways to send data over HTTP states:
203 | > GraphQL is presented as a revolutionary new way to think about APIs. Instead of working with rigid server-defined endpoints, you can send queries to get exactly the data you’re looking for in one request.
204 |
205 | With REST:
206 |
207 | ```
208 | GET /books/1
209 | {
210 | "title": "Black Hole Blues",
211 | "author": {
212 | "firstName": "Janna",
213 | "lastName": "Levin"
214 | }
215 | // ... more fields here
216 | }
217 | ```
218 |
219 | With GraphQL:
220 |
221 | ```
222 | GET /graphql?query={ book(id: "1") { title, author { firstName } } }
223 | {
224 | "title": "Black Hole Blues",
225 | "author": {
226 | "firstName": "Janna",
227 | }
228 | }
229 | ```
230 |
231 | >The core idea of REST is the resource. Each resource is identified by a URL, and you retrieve that resource by sending a GET request to that URL. You will likely get a JSON response, since that’s what most APIs are using these days.
232 | >We can see that the URL with a GraphQL query specifies the resource we’re asking for and also which fields we care about. Also, rather than the server author deciding for us that the related author resource needs to be included, the consumer of the API decides.
233 |
234 | [An Introduction to GraphQL](https://hackernoon.com/an-introduction-to-graphql-2c3f7d8fb4e0)
235 |
236 | ## Backend
237 | Modern web apps are built on sophisticated frontend frameworks like React that handles all the UI logic, even routing (`react-router`). While [any backend](https://www.wikiwand.com/en/Comparison_of_web_frameworks) will do the job and developers choose backend frameworks based on their language of choice (e.g., ruby's Ruby on Rails, python's Django, scala's Play, Haskell's Yesod etc.), a poor performing backend can really hurt your webapp's performance and scalability. We need to keep [three main things to consider](https://www.quora.com/Would-you-choose-Node-js-Express-js-or-Play-framework-Java-for-a-new-web-app-project-Why) when choosing a backend framework:
238 |
239 | * **Performance:** For backend, that means being stateless, asynchronous, and supporting non-blocking I/O. We throw out Ruby on Rails for its performance issues.
240 | * **Flexibility:** Ability to make extendable modules and add-ons to help you make anything you need for a server, such as authentication.
241 | * **Community:** IMO the most important for a startup founding or freelancer doing a lot with little/no support from a big team. A popularity of a framework contributes directly to developer productivity and framework extensibility. This is especially important for a minimal and unopinionated framework that is flexible, such as Express. We want the ability to add third-party modules to extend the capability of Express and get help from the community for a specific problem we have. There's a healthy Node.js ecosystem so you have a myriad of open source third party modules, tutorials, and an extensive knowledge repository online to help you.
242 |
243 | There are [many backend frameworks](https://gearheart.io/blog/7-best-frameworks-for-web-development-in-2017/) out there but we will be using Express, which runs in the Node.js runtime environment.
244 |
245 | ### Runtime Environment
246 | **Node.js**, or simply Node is a JavaScript runtime environment to execute JavaScript code server-side. This is the same concept as the Java Virtual Machine (JVM), which is a runtime environment for Java and languages in the Java family (e.g., Scala, Clojure, Groovy, Kotlin). Node was released in 2009 and is based on [Google Chrome's powerful JavaScript engine, V8](https://www.wikiwand.com/en/Chrome_V8).
247 |
248 | A benefit of Node compared to other frameworks (like Ruby) is Node's ability to handle requests **asynchronously**. A browser might request something from your server. The server begins responding to this request and another request comes in. Let’s say the first request requires the server to talk to an external database and the second request does not. The server can ask the external database about the first request, and while that external database is working on responding to the first request, the server can work on responding to the second request. Your server isn’t doing two things at once, but when someone else is working on something, you’re not held up waiting.
249 |
250 | ### Framework
251 | **Express.js**, or simply Express, is a framework that runs on top of the Node's web server to simplify the development of a Node app. Node provides a bevy of low-level features you’d need to build an application. But like browser-based JavaScript, its low-level offerings can be verbose and difficult to use. Express is philosophically similar to jQuery, which cuts down boilerplate code by simplifying the APIs of the browser and adding helpful new features.
252 |
253 | Express augments Node by abstracting away the low level request handling, partitioning request handling to smaller, more modular parts that can be implemented by third party libraries (e.g., `morgan` for logging all requests and `passport` for authenticating users). Without express, you have to manage one monolithic request handler function with verbose Node.js APIs. With express, you can write multiple small request handler functions that are made more pleasant by Express and its easier APIs.
254 |
255 | Most of your Express code involves writing request handler functions, and Express adds a number of conveniences when writing these.
256 |
257 | Express does not provide a lot of out-of-box features as compared to bigger (and more opinionated) frameworks such as Play; however Express is not too opinionated how you build your application so you get a lot of flexibility to make architectural decisions for your app. Although you get less out-of-the-box features with Express, there's a rich set of third-party modules (called middleware) to implement the various functions in your Express app.
258 |
259 | Hunting for the right modules and making design decisions can be a time consuming process. Downselecting from an overwhelming number of choices seems to be the theme of the JavaScript world. To make it easier, here are the best modules to implement the important functions of a server built in Express:
260 |
261 | * Logging Requests - use [`morgan`](https://www.npmjs.com/package/morgan-2)
262 | * Authentication - use [`passport`](http://www.passportjs.org/), [`nodemailer`](https://github.com/nodemailer/nodemailer)
263 | * Talk to the database - use [`mongoose`](http://mongoosejs.com/) for mongoDB or [`knex`](http://knexjs.org/) for SQL databases such as postgresQL. See [more options](https://npmcompare.com/compare/bookshelf,knex,objection,orm,sequelize) for working with SQL database.
264 | * Password treatment - use [`bcrypt-nodejs`](https://www.npmjs.com/package/bcrypt-nodejs), [`crypto`](https://nodejs.org/api/crypto.html)
265 | * Session management - use [`express-session`](https://github.com/expressjs/session) or `cookie-parser`
266 | * Environmental (make your app more configurable) - use [`dotenv`](https://github.com/motdotla/dotenv)
267 |
268 |
269 | ### Building a RESTful Backend Server to Interface With React
270 | The traditional view of a server built with Node is [this](https://hackerstribe.com/wp-content/uploads/2016/04/Node.js-Express-in-Action.pdf):
271 | >you write a single JavaScript function for your entire application. This function listens to a web browser’s requests, or the requests from a mobile application consuming your API, or any other client talking to your server. When a request comes in, this function will look at the request and determine how to respond.
272 |
273 | Express simplifie the server functionality by taking care of all the boilerplate code you need to listen to requests and responding to requests. But as frontend frameworks like React is becoming more and more sophisticated, we want to delegate all of the user interface responsbility to the client code to display views and perform routing. Implementing view logic (including when to display a certain view) would lead to under-utilization of the frontend capability and pose an obstacle to the separation of concerns between the frontend and the backend. REST API to the rescue! What we want is to implement separate the Express backend separately from the and React Frontend and integrate them via a REST API. Let's compare the interaction between the server and client with the old way without React and the new way with React and a REST API:
274 |
275 | **Routing:**
276 | Routing refers to the mapping certain HTTP requests to certain functionality. For example, when visiting the homepage, certain code should be run. For example When a browser sends a `GET` request for `/` to your server, the router needs to respond with sending HTML for the home page.
277 |
278 | * Old way: Server does all the routing. For example, if you visit the homepage (e.g., `localhost:3000/`) in a web browser, the server responds by sending you HTML. If you send a message to an API endpoint, this function could determine what you want and respond with JSON.
279 | * New way: Client does most of the URI-driven routing (assuming you have routing libraries like `react-router` installed). The server routes if the request is triggered by an external event (such as logging in via open authentication) in which case server side logic needs to initiate a redirect.
280 |
281 | **Display Dynamic Content from the DB**
282 |
283 | * Old way: User requests content (via URL pattern or button press) via a HTTP [`GET`](http://www.restapitutorial.com/lessons/httpmethods.html). Server responds to the request and grabs content from the database, renders the HTML, and sends HTML to the browser.
284 | * New way: User requests content. Server responds to the request by grabbing content from the databse same as before but sends the content as JSON to an API e.g., `/api/someStuff`. A React component that renders itself based on the `someStuff` JSON (use `isomorphic-fetch` to get that data) will update itself by updating its state variables and render the DOM to reflect changes to the JSON. This follows from the single source of truth imperative integral to React.
285 |
286 | **Update Content from the DB**
287 |
288 | * Old way: A new user fills out a signup form for your site and presses the submit button. Server gets the request to [`POST`](http://www.restapitutorial.com/lessons/httpmethods.html) new content, which entails updating the `Users` database to add new user, then redirects the user to a part of the website that only authenticated users can access, e.g., `/dashboard/` or unlocks the features of website that only users can access (see [https://www.facebook.com/](https://www.facebook.com/) before and after you login). Or another way is to use a templating engine such as `ejs` to dynamically create HTML and have the server plug dynamic content directly into the corresponding `ejs` file to be rendered.
289 | * New way: Everything is the same as the old way except for big one difference: instead of having the server switch on what feature to unlock, the client code decides what to unlock based on the authentication status provided by the server. This is essentially a session JSON that is shared globally with the React component and is updated by the server and the client (if the user presses the log out button). We want to use `redux` to keep track of the session object because that provides one source of truth for all our React components as well as the server.
290 |
291 | **Session**
292 | Because HTTP is stateless, in order to associate a request to any other request, you need a way to store user data between HTTP requests. Cookies let the browser store your session for a certain period of time so you can be kept logged in before the cookie expires even if you closes the website. The server needs to check whether the browser has any cookies, which the server can use to "log in the user on his/her behalf". Cookies expire when a specified time elapses or if the user logs out of your site.
293 |
294 | The most common external resources you’ll deal with in Express are
* Anything involving the filesystem—Like reading and writing files from your hard drive
295 | * Anything involving a network—Like receiving requests, sending responses, or sending your own requests over the internet
296 | ### Authentication
297 |
298 | **Authentication vs. Authorization**
299 | Per [This Stackoverflow Response](https://stackoverflow.com/questions/36490904/whats-the-difference-between-passport-and-oauth):
300 | Passport is authentication middleware. OAuth is authorization middleware.
301 | Passport will allow you to authenticate the user before allowing access to your API. It does not (directly, it's possible) allow to check if a user is allowed to perform an action after authentication.
302 |
303 | >Authentication is the process of ascertaining that somebody really is who he claims to be.
304 |
305 | > Authorization refers to rules that determine who is allowed to do what. E.g. Bob may be authorized to create and delete databases, while Bobbette is only authorized to read.
306 |
307 | **Open Authentication (OAuth)**
308 |
309 | OAuth was developed by Twitter and Ma.gnolia. It is a standard for the delegation of (restricted) rights.
310 |
311 | 1. OAuth - Why Open Authentication? Per [scotch.io](https://scotch.io/tutorials/the-easiest-way-to-add-authentication-to-any-app), there are a few key reasons for this, including:
312 | >
313 | * A shifting identity landscape where we are now logging in with social providers like Google, Facebook, Twitter, and others
314 | * A desire for tighter security through features like multi-factor authentication, password-less login, and single sign-on
315 | * A new approach for application architecture that makes it more difficult to implement authentication
316 |
317 | Authentication is your username + password. Authorization is what you're allowed to do.
318 |
319 |
320 | **HTTP requests from mobile web applications**
321 | Your server can send an eTag as part of the response to your client's HTTP request. The eTag is a hash digest calculated over the content sent by the server. The client can keep a copy of the eTag and next time it asks the server for an update, it can send the eTag with the HTTP request. The server can make a comparison of the eTag in the request, with the eTag calculated over the content it wants to send. If the eTags match, then the server sends a 304 status code, which notifies the client that nothing has changed since the last time the request was made so the client can use what it has stored in its persistent data store on the client side and does not need to download the data again. The eTag is a useful tool for communications between a mobile web application that requires a lot of data from the server because the mobile web app has limited data plan and downloading a lot of data drains the battery.
322 |
323 |
324 | ## Database
325 | **Why Database?**
326 |
327 | * We want our data to live on after our server goes down (either because we manually stop it or it crashes)
328 | * When we have multiple servers and one set of data that they both need to use and update
329 | * A database is essentially a file management system. It gives us a way to structure our data, query our data, etc
330 |
331 | **SQL versus NoSQL**
332 |
333 | * [This Video](https://www.youtube.com/watch?v=eM7hzKwvTq8)** compares SQL with NoSql.
334 | * SQL databases are also called relational databases. Data is stored like spreadsheets. There are columns and rows. You need to define the columns when you first create the database. Each new entry is a new row and needs to conform to the schema. You use SQL protocol to interact with the database.
335 | * NoSQL, also known as non-relational database, are not generally structured like a spreadsheet. The protocol you use to query a NoSQL database can be anything from a RESTful HTTP request (like couchdb), a JSON-like protocol (such as the BSON of MongoDB), or a SQL-like protocol (such as Cassandra's CQL)
336 |
337 |
338 | [Kristof Kovacs](https://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis?) put together a very good summary of all the different kinds of NoSQL databases and what they are good for:
339 |
340 | * MongoDB: for building a regular app that could benefit from a flexible schema for your database (such as building a website for a startup)
341 | * Redis: for building real-time stuff (such as stock prices, real-time communication, leaderboards)
342 | * Cassandra: for big data. It lets you use SQL-like queries, which can allow data scientists to port over their existing SQL skills.
343 | * HBase: for needing to store a gigantic table (e.g., to do matrix multiplication on or something). For example, a search engine like Google. This is based on Google's BigTable, with support for Map/reduce with Hadoop. Alternative are Accumulo, Hypertable.
344 | * Note: If you are building a social network, don't be tempted to use BigTable to store graph. It's not efficient and you could have a very sparse table. Use a graph database, such as
345 |
346 | ## Stack
347 |
348 | **MERN Stack**
349 |
350 | 
351 |
352 | [Source](https://www.mongodb.com/blog/post/the-modern-application-stack-part-1-introducing-the-mean-stack)
353 |
354 | ## Tools
355 | **Node Package Manager (NPM)**
356 | Every Node project sits in a folder, and at the root of every Node project there’s a file called `package.json`, which is a pretty simple JSON file that defines project metadata like the name of the project, its version, and its authors. It also defines the project’s dependencies.
357 |
358 | [react express](http://www.react.express/npm)
359 | >`npm` uses a file named `package.json` to record which packages your app depends on. This package.json file should live in the top level directory of your React project.
360 |
361 | >To add a package.json to a project, run `npm init`
362 |
363 | >When you type `npm install` npm automatically downloads all dependencies into a folder called `node_modules`. This folder will live alongside your package.json.
364 |
365 |
366 | **Webpack**
367 |
368 | [react express](http://www.react.express/webpack)
369 | >Webpack bundles your client-side code (JavaScript, css, etc) into a single JavaScript file. Webpack is highly configurable with plugins, allowing you to bundle nearly any kind of asset imaginable.
370 |
371 |
372 | **Git / Github**
373 | [See My Tutorial](https://github.com/xiaoyunyang/xiaoyunyang.github.io/blob/master/assets/md/GitTutorial.md)
374 |
375 | ## Good Resources
376 | **Web Technology 101:**
377 |
378 | * [Web Technology Fundamentals](http://chimera.labs.oreilly.com/books/1230000000345/ch03.html)
379 | * [Frontend Backend DevOps Roadmap](https://github.com/kamranahmedse/developer-roadmap)
380 |
381 | **Web App Design Guides**
382 |
383 | **Frontend**
384 |
385 | * [React.Express Tutorial](http://www.react.express) - Learn about React, Redux, ES6, Babel, Webpack
386 | * [React-Redux Connect Explained](https://www.sohamkamani.com/blog/2017/03/31/react-redux-connect-explained/)
387 | * [Material Design](http://www.google.com/design/spec/material-design/introduction.html) - Best practice for UX and UI
388 | * [Frontend Handbook](https://frontendmasters.com/books/front-end-handbook/2017/)
389 |
390 | **Backend**
391 |
392 | * [Manning Express In Action](https://hackerstribe.com/wp-content/uploads/2016/04/Node.js-Express-in-Action.pdf)
393 | * [Express In Action Code](https://github.com/EvanHahn/Express.js-in-Action-code)
394 | * [How to Integrate React Router v4 with Server Router](https://crypt.codemancers.com/posts/2017-06-03-reactjs-server-side-rendering-with-router-v4-and-redux/)
395 |
396 | **REST API**
397 |
398 | * [REST API tutorial](http://www.restapitutorial.com/)
399 |
400 | ## TODO
401 | - [ ] Integrate [resources from here](https://www.reddit.com/r/LearnFree/comments/6p2p4a/list_of_best_online_resources_to_learn/) to this document.
402 | - [ ] Add self-directed learning guide section to this document.
403 | - [ ] Go through the [Awesome List](https://github.com/sindresorhus/awesome)
--------------------------------------------------------------------------------
/fundamental/why-work-with-go.md:
--------------------------------------------------------------------------------
1 | # Writing a server with Go
2 | 
3 |
4 | ## What is Go
5 | [Go](https://github.com/golang/go) is a programming language created by Google. It started as an experiment by some engineers, to develop to address the pain points of C++ and Java without compromising performance and capability that those languages provides. Other than a well-thought design, it has some specific features for concurrency like a type of light-weight processes called goroutines.
6 |
7 | In [Tomassett's blog article](https://tomassetti.me/best-programming-languages/) on best articles for each situation, he writes:
8 |
9 | > All its [Go's] authors expressed a dislike for C++ complexity. So, in some way, it is a language designed to persuade C people to enter the new century.
10 |
11 | ## Why You Should Go with Go
12 |
13 | 1. It's [easy to learn](https://movio.co/en/blog/migrate-Scala-to-Go/).
14 | 2. It let's you do concurrency without the overhead.
15 | 3. It's type safe.
16 | 4. It's fast.
17 |
18 |
19 | ## Features of Go
20 |
21 | * Easy to learn - [See this article](https://movio.co/en/blog/migrate-Scala-to-Go/)
22 |
23 | **What is concurrency and why we care**
24 |
25 |
26 |
27 | ## Go Offers Best Balance
28 |
29 | Tradeoffs Programmers Need To Make and How Go
30 |
31 | [Tomassett's blog article](https://tomassetti.me/best-programming-languages/) on best articles for each situation discusses when to use different languages. I'm going to discuss design patterns for each situation.
32 |
33 | **Code reusability vs. code scalability**
34 |
35 | Object oriented programming (OOP) make sense for enterprise software because they don't change that much. In OOP behavior is hard coded in abstract classes but is configurable to some extent during construction. This promotes better code reuse, which saves developers a lot of time upfront. However, if you expect your code to extend more capability later and have to revise your design many times in the future, then OOP will end up hurting developer productivity and make the code highly coupled with the environment and untestable.
36 |
37 | are often conflicting design goals but they don't have to be.
38 |
39 | **Performance/Correctness vs rapid development**
40 | Languages like C, C++, and Java offer great performance but takes long to develop and compile time ramps up when your code grows. These languages often provide type safety features such as static type checking at compile time, which contributes to compile time.
41 |
42 | Type checking at compile time is a useful feature to prevent type errors (inconsistencies). Languages that support dynamic typing doesn't help you catch type errors and let these type errors manifest in runtime errors, or worse, incorrect or inconsistent behavior during runtime, which would result in many hours of debugging.
43 |
44 | Having to compile before you can run your code can really hurt rapid development. That's why languages like Ruby and Python are popular with developers concerned with making something quick.
45 | 
46 |
47 | But Ruby and python are notorious for being slow.
48 |
49 |
--------------------------------------------------------------------------------
/guides/auth-setup.md:
--------------------------------------------------------------------------------
1 | # Authentication and Database Setup
2 |
3 | ## Goal
4 | We want to build a `react` and `node` app with user authentication via `passport`, `mongo` for database, and `mongoose` to connect the app to the database.
5 |
6 | ## Middleware
7 |
8 | **Authentication**
9 |
10 | * [`passport`](http://www.passportjs.org/), which help us authenticating with different methods includes these add-ons to help us authenticate with different methods:
11 | * [`passport-local`]()
12 | * [`passport-facebook`]()
13 | * [`passport-google-oauth`]()
14 | * [`passport-github2`](https://www.npmjs.com/package/passport-github2)
15 | * [`passport-local-mongoose`](https://github.com/saintedlama/passport-local-mongoose)
16 | * [`dotenv`](https://github.com/motdotla/dotenv)
17 | * [`nodemailer`](https://github.com/nodemailer/nodemailer)
18 | * [`body-parser`](https://github.com/expressjs/body-parser) - parsing `POST` request bodies to get information from html forms. For example, when a user submits a form.
19 |
20 | **Session**
21 |
22 | * [`express-session`](https://github.com/expressjs/session)
23 | * [`cookie-parser`]() - read cookies from users (needed for auth). This needs to be paired with another Express-supported middleware like `express-session`. Once you've done this, you can keep track of users, providing them with user accounts and other features.
24 | * [`cookie-session`](https://github.com/expressjs/cookie-session) - stores the session data on the client within a cookie, while a module like `express-session` stores only a session identifier on the client within a cookie and stores the session data on the server, typically in a database.
25 |
26 | **Database**
27 |
28 | * [`mongoose`](http://mongoosejs.com/docs/connections.html)
29 | * [`mongo`](https://www.tutorialspoint.com/mongodb/mongodb_data_modeling.htm)
30 | * [`knex`](http://knexjs.org/) - SQL query builder for Postgres. Our app uses `knex` to interact with the database.
31 |
32 | **Security**
33 |
34 | * [`bcrypt-nodejs`](https://www.npmjs.com/package/bcrypt-nodejs) - used to hash strings and compare the hash with the hash stored in the database
35 | * [`crypto`](https://nodejs.org/api/crypto.html) - nodes's built in module for hashing. Deprecated.
36 | * [`helmet`](https://github.com/helmetjs/helmet) - Helps to secure your applications. It doesn’t magically make you more secure, but a small amount of work can protect you from a lot of hacks.
37 |
38 |
39 | **Utilities**
40 |
41 | * [`connect-flash`]() - allows for passing session flashdata messages.
42 | * [`morgan`](https://www.npmjs.com/package/morgan-2) - log every request to the console
43 | * [`dotenv`](https://github.com/motdotla/dotenv)
44 | * [`compression`](https://github.com/expressjs/compression) - Compression for compressing responses to save on bytes
45 | * [`connect-assets`](https://github.com/adunkman/connect-assets) —Compiles and minifies your CSS and JavaScript assets. It will also work with CSS preprocessors like SASS, SCSS, LESS, and Stylus, should you choose to use them.
46 |
47 | ## Set up the `User` model
48 | You want to sign up users and log users in to use your website. We need to create a `User` object. From your project directory:
49 |
50 | ```
51 | $ mkdir models
52 | $ touch models/User.js
53 | ```
54 | The `User` model will include logic for authentication, including:
55 |
56 | * Hooking up to a `users` table in the postgresql database
57 | * When a new user signs up, create a new `User` with the information provided by the user and saving all that information into the `users` table in the database. We don't want to save the raw password into the database because if your database gets hacked, the hacker will have the login information of all your users. A mitigation for that is to hash the password with secure hash algorithm (SHA) and store the hash into the database.
58 | * Next time returning user tries to log in with the password, you hash the password and compare the hash of the password with the stored hash in the database. If they match, the user is authenticated and gets logged in. If the hashes don't match, then the user can click on a "forgot my password" link to reset the password. Note, we can't tell the user what the password is because SHA is a one way function, meaning it is not possible to guess what the original password is using just the hash.
59 | * Dependencies to achieve these goals:
60 | * [`knex`](http://knexjs.org/) - SQL query builder for Postgres. We use `knex.js` to interact with the database.
61 |
62 | ```
63 | $ mkdir models/dbconfig
64 | $ touch models/dbconfig/bookshelf.js
65 | $ touch models/dbconfig/knexfile.js
66 | $ touch models/dbconfig/.env
67 | ```
68 | **What is salt and what it's good for?**
69 |
70 | > [Salt](https://www.wikiwand.com/en/Salt_(cryptography)) is random data that is used as an additional input to a one-way function that "hashes" data, a password or passphrase. Salts are closely related to the concept of nonce. The primary function of salts is to defend against dictionary attacks or against its hashed equivalent, a pre-computed rainbow table attack
71 |
72 | > [Rainbow tables](https://www.wikiwand.com/en/Rainbow_table) are one tool that has been developed to derive a password by looking only at a hashed value.
73 | >
74 | > It is a practical example of a space–time tradeoff, using less computer processing time and more storage than a brute-force attack which calculates a hash on every attempt, but more processing time and less storage than a simple lookup table with one entry per hash. Use of a key derivation function that employs a salt makes this attack infeasible.
75 |
76 | **More on cryptographic hash functions**
77 |
78 | * You can think about a hash digest as a fingerprint for the data.
79 | * A hash digest is the output of a hash function. A hash function takes an input and produces a unique output. A cryptographic hash function such as SHA-256 is designed to be a one way function and has the property that any small change to the input will produce a large and unpredictable change to the output.
80 | * It is not computationally feasible to deduce the original data from the hash digest generated by the secure hash algorithm. The only way to get the original data is by brute forcing or make a space time tradeoff and mount a rainbow table attack.
81 | * SHA-256 always outputs 256 bits for any size input. This translates to 64 hexadecimal characters.
82 | * Note: There are things you can do such as add a salt to your hash calculation to mitigate a rainbow table attack. But we are going off topic.
83 | * This [stackoverflow response](https://stackoverflow.com/questions/28942244/when-to-use-salt-with-message-digest) explains the salt very well:
84 | > You can use “[salt](https://en.wikipedia.org/wiki/Salt_%28cryptography%29)”, which refers to a small, random input to the hash function that is used to alter the state of the function prior to adding additional input that may be predictable in some way. This is a security mechanism that was developed for protecting passwords when using a message digest as a password verifier function. If a salt is not used, then any users having the same password will have the same password hash stored in the user database. Enormous efficient hash reversal tables ("[rainbow tables](https://www.wikiwand.com/en/Rainbow_table)") exist for the most common message digest functions used in this manner (MD5, NTLM password hash, etc.), and an attacker who obtains the database has only to perform a table lookup to obtain the plaintext password of every user. Using a salt prevents the generation of these tables, since each byte of salt results in a 256x size increase of the lookup table.
85 | > A message digest (also known as a "hash") is the output of a digest or [cryptographic hash function](https://www.wikiwand.com/en/Cryptographic_hash_function), which is a one-way fixed-size-output compression function having the property that small changes to the input (message) result in large, unpredictable changes in the output digest. How to use such a function depends greatly on what you are trying to do with it
86 |
87 | ## Set up the Authentication Process
88 |
89 | **What is authentication?**
90 |
91 | It's a way to verify the person visiting your webpage has the right credentials to access the webpage. Credentials are extracted from cookies, sessions, and user login.
92 |
93 |
94 | **What is passport?**
95 |
96 | `passport` is an authentication middleware for node. Passport implements the boilerplate code for authenticating the user so you don't have to write the boilerplate code yourself.
97 |
98 | **Passport Setup**
99 |
100 | 1. Create a config file for passport
101 | ```
102 | $ touch config/passport.js
103 | ```
104 | 2. Follow the scotch.io tutorials to populate the `config/passport.js` file to use different strategies to log in/sign up
105 | * [Set up local](https://scotch.io/tutorials/easy-node-authentication-setup-and-local)
106 | * [Set up oAuth](https://scotch.io/tutorials/easy-node-authentication-facebook)
107 |
108 | The `config/passport` file will end up looking like this after you set passport up to use both local and facebook strategies:
109 |
110 | ```javascript
111 | // config/passport.js
112 |
113 | const LocalStrategy = require('passport-local').Strategy;
114 | const FacebookStrategy = require('passport-facebook').Strategy;
115 | const User = require('../models/user');
116 |
117 | // You are exporting a function that takes passport as
118 | // an argument and returning
119 | module.export = (passport) => {
120 |
121 | /** passport session setup **/
122 | // required for persistent login session
123 | passport.serializeUser((user, done) => { /* TODO */ }
124 | passport.deserializeUser((id, done) => { /* TODO */ }
125 |
126 | /** Local Signup **/
127 | passport.use('local-signup', new LocalStrategy( /* TODO */ ))
128 |
129 | /** Facebook Signup **/
130 | passport.use('facebook-signup', new FacebookStrategy( /* TODO */ ))
131 | }
132 | ```
133 | 3. We pass this `config/passport.js` file into `server.js` to configure `passport`. `server.js` contains the following code:
134 |
135 | ```javascript
136 | // server.js
137 |
138 | const passport = require('passport')
139 | require('./config/passport')(passport);
140 |
141 | ```
142 |
143 | **Set up passport with auth0**
144 |
145 | [https://github.com/auth0/passport-auth0](https://github.com/auth0/passport-auth0)
146 |
147 | ## Set up Open Authentication With Passport
148 |
149 | To use any of the included OAuth providers (e.g. Facebook, Twitter, Google), you will need to **obtain API keys**. I have included "throw-away" API keys for all OAuth providers to get you up and running quickly, but be sure to update them with your own keys.
150 |
151 | ### Facebook
152 | [Read the official doc](https://developers.facebook.com/docs/facebook-login/web) and Check out the [Facebook Developer help community](https://www.facebook.com/help/community/question/?id=237899156642623)
153 |
154 | 1. Go to [Facebook Developers](https://developers.facebook.com/). Click on **My Apps** dropdown, then select **Add a New App**.
155 | 2. Select **Website** platform, then click on **Skip and Create App ID** button.
156 | - Enter a **name** and choose a **category** for your app.
157 | - Click on **Create App ID** button.
158 | 3. Under Products > Facebook Login > QuickStart, click on **+ Add Platform** button. Facebook will ask you "Tell us what the URL of your site is". Make sure Site URL is `http://localhost:3000/auth/facebook/callback`.
159 | 4. Under Products > Facebook Login > Settings,
160 | - ensure Valid OAuth redirects URIs is `http://localhost:3000/auth/facebook/callback`, which should match Site URL from the previous step.
161 | - Make sure you turn on "Client OAuth Login" and "Web OAuth Login"
162 | 4. Copy and paste **App ID** and **App Secret** keys into `.env` file:
163 | - `FACEBOOK_ID='YOUR_APP_ID'`
164 | - `FACEBOOK_SECRET='YOUR_APP_SECRET'`
165 |
166 | ### Google
167 | 1. Go to [Google Cloud Console](https://cloud.google.com/console/project), then select **Create project**.
168 | - Enter a **Project name**, then click on **Create** button.
169 | - Click on **Use Google APIs** (Enable and manage APIs) panel.
170 | 2. Click on **Credentials** tab in the sidebar. Click on **Create credentials** dropdown, then select **OAuth client ID**. Select or enter the following:
171 | - **Application type**: `Web application`
172 | - **Authorized JavaScript origins**: `http://localhost:3001`
173 | - **Authorized redirect URIs**: `http://localhost:3001/auth/google/callback`
174 | - Click on **Create** button.
175 | 3. Copy and paste **client ID** and **client secret** keys into `.env` file:
176 | - `GOOGLE_ID='YOUR_CLIENT_ID'`
177 | - `GOOGLE_SECRET='YOUR_CLIENT_SECRET'`
178 |
179 | ### Twitter
180 | 1. Go to [Twitter Application Management](https://apps.twitter.com/).
181 | 2. Click on **Create New App** button. Fill out required fields. - **Callback URL**: `http://127.0.0.1:3001/auth/twitter/callback`
182 | 3. Go to **Settings** tab.
183 | - Click on **Allow this application to be used to Sign in with Twitter** checkbox.
184 | - Click on **Update Settings** button.
185 | 4. Go to **Keys and Access Tokens** tab. Copy and paste **Consumer Key** and **Consumer Secret** keys into `.env` file:
186 | - `TWITTER_ID='YOUR_CONSUMER_KEY'`
187 | - `TWITTER_SECRET='YOUR_CONSUMER_SECRET'`
188 |
189 | ### Github
190 | 1. Go to [Github Developer Applications Settings](https://github.com/settings/developers)
191 | 2. Click on **Register a new application** button. Fill out required fields.
192 | - **Application Name**
193 | - **Homepage URL**
194 | - **Callback URL**: `http://127.0.0.1:3001/auth/github/callback`
195 | - Click on **Register application**
196 | 3. Copy and paste **client ID** and **client secret** keys into `.env` file:
197 | - `GITHUB_ID='YOUR_CLIENT_ID'`
198 | - `GITHUB_SECRET='YOUR_CLIENT_SECRET'`
199 |
200 | Note: If you are using React or AngularJS, copy and paste client secret into .env file and client ID into app/actions/oauth.js (React) and app/app.js (AngularJS).
201 |
202 | ## Integration With React Router
203 |
204 | Check out [this tutorial](https://tylermcginnis.com/react-router-protected-routes-authentication/)
205 |
206 | [This Stackoverflow post](https://stackoverflow.com/questions/43164554/how-to-implement-authenticated-routes-in-react-router-4) suggests creating a `PrivateRoutes` component:
207 |
208 |
209 | Same Tutorial is found here: [React Training](https://reacttraining.com/react-router/web/example/auth-workflow)
210 |
211 | [`react-router-config`](https://github.com/ReactTraining/react-router/tree/master/packages/react-router-config)
212 |
213 | * According to the [documentation](https://reacttraining.com/react-router/web/example/route-config), you can do something like this:
214 |
215 | ```javascript
216 | const routes = [
217 | { path: '/sandwiches',
218 | component: Sandwiches
219 | },
220 | { path: '/tacos',
221 | component: Tacos,
222 | routes: [
223 | { path: '/tacos/bus',
224 | component: Bus
225 | },
226 | { path: '/tacos/cart',
227 | component: Cart
228 | }
229 | ]
230 | }
231 | ]
232 |
233 | // wrap and use this everywhere instead, then when
234 | // sub routes are added to any route it'll work
235 | const RouteWithSubRoutes = (route) => (
236 | (
237 | // pass the sub-routes down to keep nesting
238 |
239 | )}/>
240 | )
241 |
242 | ```
243 | `react-router-config` issues:
244 | * [Issue 5138](https://github.com/ReactTraining/react-router/issues/5138)
245 | * [Issue 4962](https://github.com/ReactTraining/react-router/issues/4962)
246 |
247 | [Tutorial](https://www.mokuji.me/article/react-auth0) for implementing react-node app with authentication using auth0.
248 |
249 |
250 | ## Set up your Database
251 |
252 | ### MongoDB
253 | * Install MongoDB:
254 |
255 | ```
256 | $ brew install mongodb
257 | ```
258 | * Create the data directory:
259 |
260 | ```
261 | $ sudo mkdir -p /data/db
262 | ```
263 | * Set permissions for the data directory:
264 |
265 | ```
266 | $ sudo chown -R `whoami` /data/db
267 | ```
268 | * Run MongoDB server in one terminal and then MongoDB shell in another terminal:
269 |
270 | ```
271 | $ mongod
272 | ```
273 |
274 | ```
275 | $ mongo
276 | >
277 | ```
278 |
279 | * Install [Mongo.app](http://mongoapp.com/), which lets you launch an application that runs in the menu bar at the top right of your screen. You can tell when it’s running and when it’s not, easily start up a console, and shut it down effortlessly.
280 |
281 | * Things you can do in the mongoDB shell ([Quick Reference](https://docs.mongodb.com/manual/reference/mongo-shell/))
282 |
283 | ```
284 | > show dbs $ see all available databases
285 | > use test $ switch to db test
286 | > db $ see which data you are using currently
287 | > show collections $ list all collections inside current db
288 | users
289 | > db.users.find() $ in the users collection, return all documents
290 | > db.users.remove( { } ) $ remove all documents in the users collection
291 | > db.users.remove( { index } )
292 | > db.users.dropIndexes()
293 |
294 | ```
295 |
296 | **Resources**
297 | * [Azat Marda's Cheatsheet](https://github.com/azat-co/cheatsheets/tree/master/mongodb-mongoose)
298 | * [Little Mongo Handbook](http://openmymind.net/mongodb.pdf)
299 | * MongoDB's [official documentation](https://docs.mongodb.com/manual/mongo/)
300 |
301 |
302 | ### PostgreSQL
303 |
304 | ##### Install Postgres
305 | Using Homebrew: `$ brew install postgres`
306 | ##### Start Postgres
307 | * Automatic:
308 | * `pg_ctl -D /usr/local/var/postgres start && brew services start postgresql` - This makes Postgres start every time your computer starts up. Execute the following command
309 | * `brew services start postgresql` - To have launchd start postgresql now and restart at login
310 | * Manual
311 | * Start Postgres: `$ pg_ctl -D /usr/local/var/postgres start`
312 | * Stop Postgres: `$ pg_ctl -D /usr/local/var/postgres stop`
313 |
314 | ##### Database Management
315 | * `> createdb looseleaf` - creates a database called looseleaf
316 | * `> dropdb looseleaf` - delete the database called looseleaf
317 | * `> psql looseleaf` - run the database called looseleaf. After you type this, you'll see this: `looseleaf=#`, which is the header for the postgres database interface. Type the command after the `#`. For example:
318 | * `looseleaf=# \du` - see what users are installed
319 | * `looseleaf=# \h` - help
320 | * `looseleaf=# \q` - quit
321 | If you want to use a PostgresQL GUI, install and launch [Postico](https://eggerapps.at/postico/). Look up the User name using `looseleaf=# \du`.
322 |
323 | Integrate Postgres with your Node app:
324 |
325 | * Link database to your app: In the `.env` file in the root directory of the app, edit the DB_NAME line to say `DB_NAME='looseleaf'` and change `DB_USER` to the name as appeared when you run the `looseleaf=# \du` command above.
326 | * If you don't start the database before you run `npm start`, then you will get a "Knex: Error Pool 2 - Error: connect ECONNREFUSED" error.
327 |
328 | ## Connect App To Database
329 | we can use [`mongoose`](http://mongoosejs.com/) to provide database access for our application.
330 |
331 | * [Mozilla Tutorial for Express-Nodejs-mongoose setup](https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose)
332 | * [mongoose getting started](http://mongoosejs.com/docs/index.html)
333 | * [Connect mongoose to mongodb](http://mongoosejs.com/docs/connections.html)
334 |
335 | [mongoose Schemas](http://mongoosejs.com/docs/guide.html)
336 | > Do not declare methods using ES6 arrow functions (=>). Arrow functions [explicitly prevent binding](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_binding_of_this) this, so your method will not have access to the document and the above examples will not work.
337 |
338 |
339 | ## Debugging
340 | * [`node-inspector`](https://github.com/node-inspector/node-inspector)
341 | * node-inspector is great, but due to a [current bug](https://github.com/node-inspector/node-inspector/issues/905), it won’t work on any version of Node higher than 6.3.1.
342 | * [This article](https://team.goodeggs.com/visual-debugging-with-es6-and-node-js-44631b3b040f) discusses options for debugging in Node, in particular `node-inspector` and JetBrains Webstorm.
343 | * [`node-devtools`](https://www.npmjs.com/package/node-devtools) - not working
344 | * [Official doc for create-react-app](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#debugging-in-the-editor)
345 |
346 | ## Babel
347 |
348 | * [What is Babel?](https://kleopetrov.me/2016/03/18/everything-about-babel/)
349 | * [How to set up Babel](http://www.react.express/babel)
350 |
351 | ```
352 | $ npm install --save-dev babel-loader babel-core babel-preset-react babel-preset-env babel-preset-stage-1 babel-plugin-transform-runtime
353 | $ npm install --save babel-runtime
354 | ```
355 | * `babel-preset-es2015` is deprecated. Use `babel-preset-env` instead. [Read about it here](http://babeljs.io/env)
356 |
357 | `babel-preset-env` node [not working](https://github.com/facebookincubator/create-react-app/issues/1125) in create-react-app
358 |
359 |
360 |
361 |
362 | ## WebApp Environmental
363 | Accessing environment variables in Node.js is supported right out of the box. When your Node.js process boots up it will automatically provide access to all existing environment variables by creating an `env` object as property of the `process` global object. If you want to take a peek at the object run the the Node.js REPL with `node` in your command-line and type:
364 |
365 | ```javascript
366 | console.log(process.env);
367 | ```
368 | You should see that the value of `PORT` is `undefined` on your computer. Cloud hosts like Heroku or Azure, however, use the `PORT` variable to tell you on which port your server should listen for the routing to work properly. Therefore, the next time you set up a web server, you should determine the port to listen on by checking `PORT` first and giving it a default value otherwise:
369 |
370 | ```javascript
371 | const app = require('http').createServer((req, res) => res.send('Ahoy!'));
372 |
373 | // take the value of the PORT if it’s available or default
374 | // to 3000 as a fallback port to listen on.
375 | const PORT = process.env.PORT || 3000;
376 |
377 | app.listen(PORT, () => {
378 | console.log(`Server is listening on port ${PORT}`);
379 | });
380 | ```
381 |
382 | According to node's documentation on the [`process-env`](https://nodejs.org/docs/latest/api/process.html#process_process_env)
383 | >It is possible to modify this object, but such modifications will not be reflected outside the Node.js process.
384 |
385 | If you want to separately define your environmental variable, then install `dotenv` and use the following lines in your `server.js`.
386 |
387 | What it is:
388 | >`Dotenv` is a zero-dependency module that loads environment variables from a `.env` file into `process-env`.
389 |
390 | Why you shoud use it:
391 | >`Dotenv` is a simple way to allow you to create secret keys that your application needs to function and keep them from going public.
392 |
393 | See more on why you should use of [`Dotenv`](https://github.com/motdotla/dotenv) from [this article](https://medium.com/@thejasonfile/using-dotenv-package-to-create-environment-variables-33da4ac4ea8f).
394 |
395 |
396 | ## More Things to Checkout
397 | [Sample App](https://github.com/aybmab/express-redux-sample)
398 |
399 | **A User System**
400 | Use `passport` to implement a user system. Essentially, a session token is generated when a client connects, it is then associated with an account if the user successfully signs on and saved to a store (currently the dev session store, but soon to be redis - though it could also be saved in the DB). The token is then used to authorize subsequent requests.
401 |
402 | **Redux**
403 | Everytime something happens, a new state object is created to reflect the change, and the views update accordingly.
404 |
405 | **Optimistic Updates:**
406 |
407 | > After having a redux application connected to a backend, I wanted to implement optimistic updates (a.k.a. reflect user updates immediately, even though the change wasn't necessarily saved). This was implemented by generating a unique id on the client side and then using that to reconcile after hearing back from the server. By using the client-side-generated id, react nicely handles updating the view and notifying the user on the status of each change.
408 |
409 | **Live Update/Push Notification**
410 | > After users were able to make changes, I didn't want them to have to refresh their page to see changes made by other users. I used [SocketIO](https://socket.io/) to alert each client of any update. Please let me know what you think about this! I've never used backbone, but it seems to have a nice model and event system that could be worth exploring.
411 |
412 | **Sessions**
413 | Sessions are basically cookies that also gives you the ability to define the backend storage used by the server part of your application
414 |
415 | **Client Side Routing**
416 |
417 |
418 | ## Resources
419 | * Why [open authentication](https://scotch.io/tutorials/the-easiest-way-to-add-authentication-to-any-app)?
420 | * [`passport-mongo-local`](https://github.com/saintedlama/passport-local-mongoose)
421 | * [Connect mongoose to mongodb](http://mongoosejs.com/docs/connections.html)
422 | * Passport Tutorial
423 | * Scotch.io - [set up passport-local](https://scotch.io/tutorials/easy-node-authentication-setup-and-local)
424 | * Scotch.io - [set up passport-facebook](https://scotch.io/tutorials/easy-node-authentication-facebook)
425 | * DJAMware - [Set up passport with facebook twitter, Google, and Github login](https://www.djamware.com/post/59a6257180aca768e4d2b132/node-express-passport-facebook-twitter-google-github-login)
426 | * [node passport and postgres setup](http://mherman.org/blog/2016/09/25/node-passport-and-postgres/) - Good tutorial on integrating `passport` with `postgres` and `knex`
427 | * [postgres with passport](http://uitblog.com/postgres-with-passport/)
428 | * [node passport and postgres](https://reallifeprogramming.com/node-authentication-with-passport-postgres-ef93e2d520e7)
429 | * [codeMentor](https://www.codementor.io/devops/tutorial/getting-started-postgresql-server-mac-osx) - Getting Started Tutorial for postgresql
430 | * [node passport and postgres setup](http://mherman.org/blog/2016/09/25/node-passport-and-postgres/)
431 | * [node passport and mongo setup](http://mherman.org/blog/2013/11/11/user-authentication-with-passport-dot-js/#setup)
432 | * [postgres with passport](http://uitblog.com/postgres-with-passport/)
433 | * [TutorialsPoint MongoDB Tutorial](https://www.tutorialspoint.com/mongodb/mongodb_overview.htm)
434 | * [MongoDB official documentation](https://docs.mongodb.com/manual/mongo/)
435 | * [Postgres vs Mongo - Youtube video](https://www.youtube.com/watch?v=eM7hzKwvTq8)
436 | * [best practice for handling sessions in redux](https://github.com/reactjs/redux/issues/297)
--------------------------------------------------------------------------------
/guides/coding-best-practice.md:
--------------------------------------------------------------------------------
1 | ## JavaScript Coding Best Practice
2 |
3 | | Name | In Code | When to use |
4 | |------------|---------------|--------------------------|
5 | | PascalCase | `SomeSymbol` | Class/Object names |
6 | | camelCase | `someSymbol` | variable names |
7 | | snake_case | `SOME_SYMBOL` | enumerated / state names |
8 | | kebab-case | `some-symbol` | URLs and files |
9 |
10 |
11 | ### Resources
12 | * [Airbnb's JavaScript Style Guide](https://github.com/airbnb/javascript)
13 | * [Wearhive's List Of Best Practices for JavaScript Projects](https://github.com/wearehive/project-guidelines#readme) 😍
--------------------------------------------------------------------------------
/guides/d3-react-integration.md:
--------------------------------------------------------------------------------
1 | # How to Properly Integrate D3 into React
2 |
3 | [Performance Models](http://www.react.express/performance_model)
4 | >Modifying the DOM is slow. React is built to modify that DOM as little as possible. React builds an in-memory representation of the components you render, and then syncs this representation to the DOM. As you update components, React will update the in-memory representation, and then make the least amount of changes to the DOM possible.
5 |
6 | This is an important point if you want to add `d3` to React. You do not want to make the `d3` "component" part of the DOM; rather, you want to allow React high level control over what `d3` takes as input to render itself and sync `d3`'s data model (i.e., `csv` or `json`) with a `state` variable within the React master component.
7 |
8 | >In cases where component `render` is happening too frequently and causing performance issues, React gives you more control over the component lifecycle with `shouldComponentUpdate`, allowing you to choose exactly when a component does and doesn't re-render. When this method isn't defined, components will always re-render whenever their state or props change. Defining `shouldComponentUpdate` allows you to manually compare whatever data you need to determine whether or not the component should re-render. Return true to trigger a render call and false to prevent it.
9 | >you can safely skip the `shouldComponentUpdate` until you notice sluggish app behavior.
--------------------------------------------------------------------------------
/guides/es6-and-babel.md:
--------------------------------------------------------------------------------
1 | ## Useful Stuff in ES6
2 |
3 | ES2015, or ECMAScript 2015, is the first significant update to the language since ES5 was initially released in 2009. You'll often see ES2015 called by its original name, ES6, since it's the 6th version of ECMAScript. [Check out all the cool new stuff in ES6](http://es6-features.org/#Constants)! Let's take a look at the most value-added improvements:
4 |
5 | [var let and const](http://www.react.express/block_scoped_declarations)
6 | >the [babel] compiled output replaces const and let with var. You'll also notice that Babel transforms const a = 3 into var _a = 3. This is so that your code can run on older platforms that don't support the new block-scoped variable declarations.
7 |
8 | [Fat arrow functions](http://www.react.express/fat_arrow_functions)
9 | >The fat arrow `=>` is used to define anonymous functions. There are two important differences in the behavior of these functions, compared to functions defined with `function`.
10 |
11 | >If the function body is not wrapped in curly braces (as in the previous sentences), it is executed as an expression, and the return value of the function is the value of the expression. The function body can be wrapped in curly braces to make it a block, in which case you will need to explicitly `return` a value, if you want something returned.
12 |
13 | [Destructuring](http://www.react.express/destructuring)
14 | >Destructuring is a convenient way to extract multiple keys from an object or array simultaneously and assign the values to local variables.
15 |
16 | [Imports and exports](http://www.react.express/imports_and_exports)
17 | >There is one default export per file, and this exported value can be imported without refering to it by name. Every other import and export must be named.
18 |
19 | [Default Parameters](http://www.react.express/default_parameters)
20 |
21 | ```javascript
22 | const printInput = (input = 'hello world') => {
23 | console.log(input)
24 | }
25 |
26 | printInput()
27 | printInput('hello universe')
28 | ```
29 |
30 | [Classes](http://www.react.express/classes)
31 | >In ES5, classes are written as functions, with instance methods assigned to `MyFunction.prototype`. ES2015 allows us to use the simpler `class` syntax.
32 |
33 | >`class` gives us built in instance functions, static functions, and inheritance. `constructor` is a special function that is called automatically every time a class instance is created. We can use the static keyword to declare `static` class functions. Static method calls are made directly on the class and cannot be called on instances of the class.
34 |
35 | ```javascript
36 | // Class Instance Property
37 |
38 | class Cat {
39 | name = 'Tom'
40 | state = {
41 | running: true
42 | }
43 |
44 | constructor() {
45 | console.log(this.name, this.state.running)
46 | }
47 | }
48 |
49 | new Cat()
50 |
51 | ```
52 |
53 | ```javascript
54 | // Static class property
55 | class Foo {
56 | static bar = 'hello'
57 | }
58 |
59 | console.log(Foo.bar)
60 | ```
61 |
62 | [Bound Instance Method](http://www.react.express/bound_instance_methods)
63 | >Before ES2016, you might bind functions to class instances in the `constructor`, e.g. `this.func = this.func.bind(this)`. Binding here ensures that a class's instance function is invoked with the correct context.
64 |
65 | ```javascript
66 | class Cat {
67 | constructor(name) {
68 | this.name = name
69 | }
70 | printName = () => {
71 | console.log(this.name)
72 | }
73 | }
74 |
75 | const cat = new Cat('Tom')
76 | const printName = cat.printName
77 |
78 | // 'this' is still bound to our Cat instance, so even
79 | // though our calling context changed, the function
80 | // executes in its original context.
81 | printName()
82 | ```
83 |
84 | [Dynamic Object Keys](http://www.react.express/dynamic_object_keys)
85 | [Array Spread](http://www.react.express/array_spread)
86 | [Object Spread](http://www.react.express/object_spread)
87 | >We can copy an object simply with `{...originalObj}`. Note that this is a shallow copy. We can also extend an object with `{...originalObj, key1: 'newValue'}`.
88 |
89 |
90 | ## Gotchas
91 |
92 | ### ParseInt
93 |
94 | Always use the radix parameter to specify how to parse int. When radix is unspecified, `parseInt` assumes you want to parse by base 10:
95 |
96 | ```javascript
97 | parseInt('10') //> 10
98 |
99 | // which is equivalent to
100 | parseInt('10', 10) //> 10
101 | ```
102 |
103 | We can parse by base 2 or base 16
104 |
105 | ```javascript
106 | parseInt('10', 2) //> 2
107 | parseInt('10, 16') //> 2
108 | parseInt('A', 16) //> 10
109 | parseInt('A', 10) //> NaN
110 | ```
111 |
112 | ### Callback Hell
113 | **Callback hell**, which refers to deeply nested spaghetti code that jumps all over the place, is a common problem with asynchronous code that impedes developer productivity. How do we fix the callback hell problem? Here are some workarounds:
114 |
115 | **Modularize your code**
116 |
117 | Instead of writing all your code in a deeply nested anonymous function in your async code, try taking that stuff out into a separate function.
118 |
119 | **Use `async-await`**
120 |
121 | Node [provides out-of-the-box support](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9) for `async-await`.
122 |
123 | Google provides a good [primer on async](https://developers.google.com/web/fundamentals/primers/async-functions).
124 |
125 | Async functions work like this:
126 |
127 | ```javascript
128 | async function myFirstAsyncFunction() {
129 | try {
130 | const fulfilledValue = await promise;
131 | }
132 | catch (rejectedValue) {
133 | // …
134 | }
135 | }
136 |
137 | ```
138 | [Async and Await](http://www.react.express/async_await)
139 | >We can use the `async` keyword before a function name to wrap the return value of this function in a `Promise`. We can use the `await` keyword (in an `async` function) to wait for a promise to be resolved or rejected before continuing code execution in this block.
140 |
141 | ```javascript
142 | const fetchData = async () => {
143 | return fetch('https://randomuser.me/api/')
144 | }
145 |
146 | const printData = async () => {
147 | try {
148 | const data = await fetchData()
149 | const json = await data.json()
150 | console.log(json)
151 | } catch(e) {
152 | console.error("Problem", e)
153 | }
154 | }
155 |
156 | printData()
157 | ```
158 |
159 | Here's how you integrate the async-await into your React component (make sure you install `isomorphic-fetch` first:
160 |
161 | ```javascript
162 | callApi = async () => {
163 | const response = await fetch('/api/hello');
164 | const body = await response.json();
165 |
166 | if (response.status !== 200) throw Error(body.message);
167 | return body;
168 | };
169 | componentDidMount() {
170 | this.callApi()
171 | .then(res => this.setState({ response: res.express }))
172 | .catch(err => console.log(err));
173 | }
174 |
175 | ```
176 |
177 |
178 | **Promise**
179 |
180 | * Use `Promise`, which is natively supported by ES6. Check out [the google tutorial](https://developers.google.com/web/fundamentals/primers/promises) on `Promise`.
181 | * See [Scotch.io Tutorial for Promise](https://scotch.io/tutorials/javascript-promises-for-dummies)
182 |
183 | >Async functions - making promises friendly
184 |
185 | ### Loosely Typed Javascript
186 | JavaScript is a loosely typed language, meaning you don’t have to specify what type of information will be stored in a variable in advance. Many other languages, like Java (which is completely different from JavaScript), require you to declare a variable’s type, such as int, float, boolean, or String.
187 |
188 | JavaScript, however, automatically types a variable based on what kind of information you assign to it (e.g., that `''` or `""` indicate string values).
189 |
190 | **typeof**
191 |
192 | whenever a variable’s type is in doubt, you can employ the `typeof` operator:
193 |
194 | ```javascript
195 | typeof 1 //> "number"
196 | typeof "1" //> "string"
197 | typeof [1,2,3] //> "object"
198 | typeof {"name": "john", "country": "usa"} //> "object"
199 | typeof [{"name": "john", "country": "usa"}, {"name": "mary", "country": "uk"}] //> "object"
200 |
201 | typeof trye //> "boolean"
202 | typeof (1 === 1) //> "boolean"
203 |
204 | typeof undefined //> "undefined"
205 | typeof null //> "object"
206 |
207 | const f = () => 2
208 | typeof f //> "function"
209 | ```
210 |
211 | **`==` vs `===`**
212 | The 3 equal signs mean "equality without type coercion". Using the triple equals, the values must be equal in type as well.
213 |
214 | ```javascript
215 | 1 == "1" //> true
216 | 1 === "1" //> false
217 | ```
218 |
219 | ```javascript
220 | null == undefined //> true
221 | null === undefined //> false
222 | ```
223 |
224 | ```javascript
225 | '0' == false //> true
226 | '0' === false //> false
227 | ```
228 |
229 | ```javascript
230 | 0 == false //> true
231 | 0 === false //> false, because they are of a different type
232 | ```
233 |
234 | **Null versus Undefined versus 0**
235 |
236 | ```javascript
237 | !0 //> true
238 | !null //> true
239 | !undefined //true
240 | ```
241 |
242 | ```javascript
243 | typeof undefined //> "undefined"
244 | typeof null //> "object"
245 |
246 | undefined == null //> true
247 | undefined === null //> false
248 |
249 | isNaN(1 + undefined) // true
250 | isNaN(1 + null) // false
251 | 1 + null //> 1
252 |
253 | !null //> true
254 | !undefined //> true
255 | ```
256 |
257 | ```javascript
258 | let users = [
259 | {"name": "andrew", "country": "usa"},
260 | {"name": "mary"}
261 | ]
262 |
263 | // execute this code and it'll print out:
264 | //> andrew is from usa
265 | //> mary has no country
266 | users.forEach( u => {
267 | if(u.country == null) {
268 | console.log(u.name + " has no country")
269 | }
270 | else {
271 | console.log(u.name + " is from "+ u.country)
272 | }
273 |
274 | })
275 |
276 | // execute this code and it'll print out:
277 | //> andrew is from usa
278 | //> mary is from undefined
279 | users.forEach( u => {
280 | if(u.country === null) {
281 | console.log(u.name + " has no country")
282 | }
283 | else {
284 | console.log(u.name + " is from "+ u.country)
285 | }
286 | })
287 |
288 | ```
289 |
290 | Why did the second `forEach` loop fail to print correctly? Because `u.country` returns `undefined` when no country is defined for the second user.
291 |
292 |
293 | My advice is to always use `===` since that is a more thorough check and help you avoid nasty bugs. `==` is a convenient way to checking error conditions if you're not sure if the failed operation returns `undefined` or `null` but don't do that. If you are not sure about `undefined` or `null`, then check for both:
294 |
295 | ```javascript
296 | if(u.country === undefined || u.country === null)
297 | //OR better
298 | if(!u.country)
299 | ```
300 |
301 | ### Scoping in JavaScript
302 | Many languages use block-level scope, in which variables exist only within the current “block” of code, usually indicated by curly braces (`{ }`).
303 |
304 | In JavaScript, however, variables `var` are scoped at the function level, meaning they are accessible anywhere within the function (not block) in which they reside.
305 |
306 | **Variable Hoisting**
307 |
308 | JavaScript code is usually, but not always, executed in linear, top-to-bottom order. For example, in this code, the variable `i` is actually declared before the for-loop even begins. This phenomenon is called variable hoisting. Variable declarations are hoisted up to the top of the function context in which they reside.
309 |
310 | ```javascript
311 | for (var i = 0; < a.length; i++) {
312 | console.log(a[i]);
313 | }
314 | ```
315 | ES6 introduced `let`, which lets you create [block-scoped variables without hoisting](http://es6-features.org/#BlockScopedVariables):
316 |
317 | ```javascript
318 | for (let i = 0; < a.length; i++) {
319 | console.log(a[i]);
320 | }
321 | ```
322 |
323 | ### Global Variables
324 | `window` is the topmost object in the browser’s hierarchy of JavaScript elements, and all of these objects and values you see beneath window exist at the global level. What this means is that every time you declare a new variable, you are adding a new value to `window`. This is really bad because we don't want to pollute the global namespace.
325 |
326 | There are two easy workarounds:
327 |
328 | * Declare variables only within other functions. This is not usually feasible, but the function-level scope will prevent local variables from conflicting with others.
329 | * Declare a single global object, and attach all of your would-be global variables to that object. For example:
330 |
331 | ```javascript
332 | var Vis = {}; //Declare empty global object
333 | Vis.zebras = "still pretty amazing"
334 | Vis.monkeys = "too funny LOL"
335 | Vis.fish = "you know, not bad"
336 | ```
337 |
338 | ## Array and String Functions
339 |
340 | See [Mutating vs Nonmutating array operation](https://lorenstewart.me/2017/01/22/javascript-array-methods-mutating-vs-non-mutating/)
341 |
342 | Check out [lodash](https://lodash.com/docs/4.17.4#range) and underscore for useful array operators.
343 |
344 | ### Add things to array
345 |
346 | * `array.push()` adds an item to the end of the array
347 | * `array.unshift()` adds an item to the beginning of the array.
348 |
349 | ```javascript
350 | // since the array will be mutated,
351 | // use 'let' rather than 'const'
352 | let mutatingAdd = ['a', 'b', 'c', 'd', 'e'];
353 |
354 | mutatingAdd.push('f'); // ['a', 'b', 'c', 'd', 'e', 'f']
355 | mutatingAdd.unshift('z'); // ['z', 'b', 'c', 'd', 'e' 'f']
356 | ```
357 | ### Common Algo:
358 |
359 | Match parentheses in a string.
360 |
361 | ```javascript
362 | function isBalanced(str, openCnt) {
363 | console.log('str = ', str)
364 | if (str === undefined || str === null || typeof str !== 'string') {
365 | return false;
366 | } else if (openCnt < 0) {
367 | return false;
368 | } else if( str.length === 0 && openCnt === 0) {
369 | return true;
370 | }
371 |
372 | const fst = str[0];
373 | const rst = str.slice(1);
374 | return isBalanced(rst, newOpenCnt(fst, openCnt));
375 | }
376 |
377 | const newOpenCnt = (c, openCnt) => {
378 | if(c === '(') return openCnt + 1;
379 | if(c === ')') return openCnt - 1;
380 | return openCnt;
381 | }
382 | ```
383 |
384 | ## Create array dynamically
385 | ```
386 | var vals = Array.from({length: 13}, (v,i) => i)
387 | //> (13) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
388 |
389 | vals = vals.map(v => v-1)
390 | //> (13) [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
391 |
392 | vals.map(v => ({val: v, : valIncrementer(v, false), disabled: valIncrementer(v, true) }))
393 | ```
394 |
395 | ### Get stuff from an array
396 |
397 | ```javascript
398 | const arr = [1, 2, 3, 4];
399 | const [first, second] = arr;
400 | ```
401 |
402 | ### Get last elem of an array
403 |
404 | Don't use `pop` unless you want to mutate the array:
405 |
406 | ```javascript
407 | var arr = [1,2,3]
408 | arr.pop() //>3
409 | arr //>[1, 2] ... Very Bad. Your original array got changed
410 |
411 | const arr2 = [1,2,3]
412 | arr2.pop()
413 | arr2 //> Even const can't help you
414 |
415 | const arr3 = arr
416 | arr3.pop() //>2
417 | arr //> [1] ... arr got changed even though arr3 did the pop
418 | ```
419 |
420 | Do this instead:
421 |
422 | ```javascript
423 | let arr = [1,2,3]
424 | arr.slice(-1)[0] //> 3
425 | arr //> [1, 2, 3]
426 | ```
427 |
428 | More on `Array.slice`:
429 |
430 | ```javascript
431 | let arr = [1, 2, 3]
432 | arr.slice(-1) //> [3]
433 | arr.slice(0) //> [1, 2, 3]
434 | arr.slice(1) //> [2, 3]
435 | arr.slice(2) //> [3]
436 | ```
437 |
438 | **Combine things in array**
439 |
440 | ```javascript
441 | [0, 1, 2, 3].reduce((sum, value) => { sum + value;}, 0);
442 | //> total is 6
443 | ```
444 |
445 | ```javascript
446 | ["hello","World"].reduce( (a, res) => a + res ) //> "helloWorld"
447 |
448 | ["hello","World"].reduce( (a, res) => { return a + res }, "My message: " )
449 | //> "My message: helloWorld"
450 | ```
451 |
452 | ```javascript
453 | ['a','b','c'].join("") //> "abc"
454 | ['a','b','c'].map(d => "1"+d).join(",") //> "1a,1b,1c"
455 | ```
456 |
457 | If you don’t pass in an initial value, reduce will assume the first item in your array is your initial value.
458 |
459 | **Combine sub-arrays**
460 |
461 | ```javascript
462 | // Flat
463 |
464 | const flat = (data) => data.reduce((total, amount) => {
465 | return total.concat(amount);
466 | }, []);
467 |
468 | var data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
469 | flat(data) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
470 |
471 | ```
472 |
473 | **Flatmap**
474 |
475 | Write a function that converts "hello" to "h.e.l.l.o." There're two parts to this: `flat` and `map`.
476 |
477 |
478 | ```javascript
479 | const arr = "hello".split("") //> ["h", "e", "l", "l", "o"]
480 |
481 | const matrix = arr.map(s => [s, "."])
482 | // [Array(2), Array(2), Array(2), Array(2), Array(2)]
483 | // 0: (2) ["h", "."]
484 | // 1: (2) ["e", "."]
485 | // 2: (2) ["l", "."]
486 | // 3: (2) ["l", "."]
487 | // 4: (2) ["o", "."]
488 |
489 |
490 | const flat = (data) => data.reduce((res, d) => {
491 | return res.concat(d);
492 | }, []);
493 |
494 |
495 | flat(matrix) //> ["h", ".", "e", ".", "l", ".", "l", ".", "o", "."]
496 |
497 | flat(matrix).join("") //> "h.e.l.l.o."
498 |
499 | ```
500 |
501 | **Sorting**
502 |
503 | ```javascript
504 | ['a','c','b'].sort((a,b) => a > b) //> ["a", "b", "c"]
505 |
506 | [1,3,2].sort((a,b) => a - b) //> [1, 2, 3]
507 |
508 | [1,3,2].sort((a,b) => b - a) //> [3, 2, 1]
509 |
510 | [1,3,2].sort((a,b) => b > a) //> [3, 2, 1]
511 | ```
512 |
513 |
514 | **Getting Substrings**
515 |
516 | Say we have "hello world" as our string but we only want "world". What do we do?
517 |
518 | ```javascript
519 | // Option 1: Split using RegExp, then slice and take the part of the array
520 |
521 | "hello world".split(new RegExp("hello")) //> ["", ["", "world"]]
522 | "hello world".split(new RegExp("hello")).slice(1) //> ["", "world"]
523 | "hello world".split(new RegExp("hello")).slice(1)[1] //> "world"
524 | ```
525 |
526 | ```javascript
527 | // Option 2: Slice recursively. "hello" plus space is 6 characters
528 | "hello world".slice(6) //> "world"
529 | ```
530 |
531 | Option 2 using `slice` works because a string is really just an array of characters.
532 |
533 |
534 | ## Functions
535 | Functions in JavaScript are objects. Objects are collections of name/value pairs having a hidden link to a prototype object. Objects produced from object literals are linked to Object.prototype. Function objects are linked to Function.prototype (which is itself linked to Object.prototype).
536 |
537 |
538 | Since functions are objects, they can be used like any other value. Functions can be stored in variables, objects, and arrays. Functions can be passed as arguments to functions, and functions can be returned from functions. Also, since functions are objects, functions can have methods.
539 |
540 |
541 | The function’s name is optional. The function can use its name to call itself recursively. The name can also be used by debuggers and development tools to identify the function. If a function is not given a name, as shown in the example below, it is said to be anonymous.
542 |
543 | ```javascript
544 | // Create a variable called add and store a function
// in it that adds two numbers.
var add = function (a, b) {
545 | return a + b;
546 | };
547 | ```
548 | **Method Invocation**
549 | When a function is stored as a property of an object, we call it a method. When a method is invoked, this is bound to that object. If an invocation expression con- tains a refinement (that is, a . dot expression or [subscript] expression), it is invoked as a method:
550 |
551 | ```javascript
552 | var stooge = {
553 | firstName: "Jerome",
554 | lastName: "Howard",
555 | nickname: "Curley",
556 | age: 37,
557 | sing: function(subject) {
558 | return "la la this is a song about "+ subject
559 | },
560 | introduceSelf: function() {
561 | return "my name is " + this.firstName + " " + this.lastName + ", but people call me "+ this.nickname
562 | },
563 | changeNickname: function(nickname) {
564 | this.nickname = nickname;
565 | }
566 | };
567 | stooge.sing("frog") //> "la la this is a song about frog"
568 |
569 | stooge.introduceSelf() //> "my name is Jerome Howard, but people call me Curley"
570 |
571 | stooge.changeNickname("Jerry")
572 | stooge.introduceSelf() //> "my name is Jerome Howard, but people call me Jerry"
573 | ```
574 |
575 | A method can use this to access the object so that it can retrieve values from the object or modify the object. The binding of this to the object happens at invocation time. This very late binding makes functions that use this highly reusable. Methods that get their object context from this are called public methods.
576 |
577 |
578 | ```javascript
579 | // Augment stooge object with an ageUp method.
580 | stooge.ageUp = function() {
581 | var that = this;
582 | var helper = function() {
583 | that.age = that.age+1
584 | }
585 | helper();
586 | }
587 |
588 | // Augment stooge object with a displayAge method.
589 | stooge.displayAge = function() { return this.age }
590 |
591 |
592 | stooge.displayAge() //> 37
593 | stooge.ageUp()
594 | stooge.displayAge() //> 38
595 | ```
596 |
597 | **Mistake in JavaScript's Language's Design**
598 |
599 | When a function is not the property of an object, then it is invoked as a function:
600 |
601 | ```javascript
602 | var sum = add(3, 4); // sum is 7
603 | ```
When a function is invoked with this pattern, this is bound to the global object. This was a mistake in the design of the language. Had the language been designed correctly, when the inner function is invoked, this would still be bound to the `this` variable of the outer function. A consequence of this error is that a method cannot employ an inner function to help it do its work because the inner function does not share the method’s access to the object as its this is bound to the wrong value.
604 |
605 |
606 | A bonus parameter that is available to functions when they are invoked is the `arguments` array. It gives the function access to all of the arguments that were supplied with the invocation, including excess arguments that were not assigned to parameters. This makes it possible to write functions that take an unspecified number of parameters:
607 |
608 | ```javascript
// Make a function that adds a lot of stuff.
// Note that defining the variable sum inside of
// the function does not interfere with the sum
// defined outside of the function. The function
// only sees the inner one.
var sum = function () { var i, sum = 0;
609 | for (i = 0; i < arguments.length; i += 1) {
610 | sum += arguments[i];
611 | }
612 | return sum;
};
// Invoke
document.writeln(sum(4, 8, 15, 16, 23, 42)); // 108
var array = [3, 4];
613 | sum.apply(null, array); //> 7
```
This is not a particularly useful pattern. In Chapter 6, we will see how we can add a similar method to an array.
Because of a design error, arguments is not really an array. It is an array-like object. arguments has a length property, but it lacks all of the array methods. We will see a consequence of that design error at the end of this chapter.
614 |
615 |
616 | ## Awesome JSON Stuff
617 |
618 | **What is JSON**
619 |
620 | JSON encodes data as key value pairs. It’s faster and easier to parse with JavaScript than XML.
621 |
622 | **Creating JSON**
623 |
624 | Dynamically
625 |
626 | ```javascript
627 | // ES6 Syntax
628 | [1,2,3].map(d => {
629 | return {[d]: -d}
630 | });
631 |
632 | // ES 5 Syntax
633 | [1,2,3].map(d => {
634 | var tmp = {};
635 | tmp[d] = -d;
636 | return tmp;
637 | });
638 |
639 | // or
640 | [1,2,3].map(d => ({[d]: -d}));
641 |
642 | // yields
643 | //> [{1: -1}, {2: -2}, {3: -3}]
644 | ```
645 |
646 | Statically
647 |
648 | ```javascript
649 | var stooge = {
650 | first_name: "Jerome",
651 | "last-name": "Howard"
652 | };
653 |
654 |
655 | var flight = {
656 | airline: "Oceanic",
657 | number: 815,
658 | departure: {
659 | IATA: "SYD",
660 | time: "2004-09-22 14:55",
661 | city: "Sydney"
662 | },
663 | arrival: {
664 | IATA: "LAX",
665 | time: "2004-09-23 10:42",
666 | city: "Los Angeles"
667 | }
668 | };
669 | ```
670 |
671 | A property’s name can be any string, including the empty string. The quotes around a property’s name in an object literal are optional if the name would be a legal JavaScript name and not a reserved word. So quotes are required around “last-name", but are optional around first_name. Commas are used to separate the pairs.
672 |
673 | **Converting JSON from one form to another**
674 |
675 | ```javascript
676 | // Create array of objects
677 | var foo = [1,2,3].map(d => {
678 | return {[d]: null};
679 | });
680 |
681 | // Create object with original arrays as keys and null as the values
682 | var bar = foo.reduce((acc, x) => {
683 | for (let key in x) acc[key] = x[key];
684 | return acc;
685 | }, {});
686 |
687 |
688 | ```
689 |
690 | **Retrieving Things from JSON**
691 |
692 | ```javascript
693 | stooge.first_name //> “Jerome”
694 | stooge[“last-name”] //> Howard
695 | flight.departure.IATA //> "SYD"
696 | ```
697 |
698 |
699 | The undefined value is produced if an attempt is made to retrieve a non existent member:
700 |
701 | ```javascript
702 | stooge["middle-name"] //> undefined
703 | flight.status //> undefined
704 | stooge["FIRST-NAME"] //> undefined
705 | ```
706 |
707 | The `||` operator can be used to fill in default values:
708 |
709 | ```javascript
710 | var middle = stooge["middle-name"] || "(none)";
711 | var middle = stooge["middle-name"] || "(none)”;
712 | var status = flight.status || "unknown"
713 | ```
714 |
715 | The `&&` operator can be used to guard against retrieving values from `undefined`
716 |
717 | ```javascript
718 | flight.equipment //> undefined
flight.equipment.model //> throw "TypeError"
flight.equipment && flight.equipment.model //> undefined
719 | ```
720 |
721 | **Update**
722 | If the object does not already have that property name, the object is augmented:
```javascript
723 | stooge.first_name = 'Jerome';
724 | stooge['middle-name'] = 'Lester';
stooge.nickname = 'Curly';
725 | ```
726 |
727 | **Prototype**
728 | Create new object using old object as prototype:
729 |
730 | ```javascript
731 | var anotherStooge = Object.create(stooge)
732 | anotherStooge.first_name //> "Jerome"
733 | anotherStooge.first_name = "Harry"
734 | anotherStooge.first_name //> "Harry
735 | ```
736 |
737 | You can think about the prototype as the default object. If we try to retrieve a property value from an object, and if the object lacks the property name, then JavaScript attempts to retrieve the property value from the prototype object.
738 |
739 | The prototype relationship is a dynamic relationship. If we add a new property to a prototype, that property will immediately be visible in all of the objects that are based on that prototype:
740 |
741 | ```javascript
742 | stooge.profession = "actor"
743 | anotherStooge.profession //> "actor"
744 | ```
745 |
746 | We can also delete:
747 |
748 | ```javascript
749 | delete anotherStooge.first_name //> true
750 | anotherStooge.first_name //> "Jerome"
751 | ```
752 |
753 | **Add function to Prototype**
754 |
755 | ```javascript
756 | stooge.sing = function() { return "la la la" }
757 | anotherStooge.sing() //> "la la la"
758 | ```
759 |
760 | ```javascript
761 | flight.hasOwnProperty('number') // true
flight.hasOwnProperty('constructor') // false
762 | ```
763 |
764 | Functions in JavaScript are objects.
765 |
766 | **Operations on JSON**
767 |
768 | ```javascript
769 | let users = [
770 | {"name": "andrew", "country": "usa"},
771 | {"name": "mary"}
772 | ]
773 | users[0] //> {name: "andrew", country: "usa"}
774 | users[0].country //> "usa"
775 | users[1].country //> undefined
776 | users.filter(u => u.country !== null).map(u => u.username) //> ["xy"]
777 |
778 | ```
779 |
780 | **Key operations**
781 |
782 | Get all keys from JSON
783 |
784 | ```javascript
785 | let foo = {"name": "andrew", "country": "usa"}
786 | let keys = Object.keys(foo) //> [“name”, “country”]
787 | ```
788 |
789 | **Unique Keys**
790 |
791 | Get the value associated with the key
792 |
793 | ```javascript
794 | let user = {"name": "andrew", "name": "usa"}
795 | user.name //> "andrew"
796 |
797 | ```
798 |
799 | Check if a key exists in a JSON
800 |
801 | ```javascript
802 | let user = {"name": "andrew", "country": "usa"}
803 | user.hasOwnProperty("name") //>true
804 | user.hasOwnProperty("andrew") //> false
805 | user.hasOwnProperty("country") //> true
806 | user.hasOwnProperty("city") //> false
807 | ```
808 |
809 | **JSON.stringify**
810 |
811 | ```javascript
812 | var foo = {"name": "andrew", "country": "usa"};
813 | var bar = {"name": "xiaoyun", "city": "dc" };
814 | var baz = {"name": "andrew", "country": "usa"}
815 | JSON.stringify(foo) == JSON.stringify(baz) //> true
816 | JSON.stringify(foo) === JSON.stringify(baz) //> true
817 | JSON.stringify(foo) == JSON.stringify(bar); //> false
818 | ```
819 | Then you can use `indexOf` is an operation on a `string`.
820 |
821 | ```javascript
822 | let a = JSON.stringify(foo) //> "{"name":"andrew","country":"usa”}"
823 | a.indexOf("{") //> 0
824 | a.indexOf("n") //> 2
825 | a.indexOf("france") //> -1
826 | a.indexOf("usaa") //> -1
827 | a.indexOf("usa") //> 28
828 | a.indexOf("u") //> 20
829 | a.indexOf("sa") //> 29
830 | a.indexOf("s") //> 29
831 | a.indexOf("}") //> 32
832 | ```
833 |
834 | **Swap Key and Val of JSON Objects**
835 |
836 | ```javascript
837 | const objKey = (d, i) => Object.keys(d)[i]
838 | const objVal = (d, i) => d[objKey(d,i)]
839 |
840 | // create JSON from an array of keys
841 |
842 | const swap = (data) => Object.keys(data).reduce( (obj,key) => {
843 | obj[ data[key] ] = key;
844 | return obj;
845 | },{});
846 |
847 |
848 | var data = {A : 1, B : 2, C : 3, D : 4}
849 | var newData = swap(data)
850 |
851 | console.log(newData); //> {1: "A", 2: "B", 3: "C", 4: "D"}
852 |
853 | ```
854 |
855 |
856 | **Destructuring**
857 | >Using object destructuring saves you from creating temporary references for those properties.
858 |
859 | ```javascript
860 | var user = {firstName: "amy", lastName:"winehouse"}
861 | var {firstName, lastName} = user
862 | firstName //> "amy"
863 | lastName //> "winehouse"
864 |
865 | ```
866 |
867 | **Merging two JSON objects**
868 |
869 | ```javascript
870 | let foo = {a: 'a', b: 'b'}
871 | let bar = {c: 'c', d: 'd'}
872 | let foobar = {...foo, ...bar} //> {a: "a", b: "b", c: "c", d: "d"}
873 | ```
874 |
875 | ### Practice
876 |
877 | **Given**
878 |
879 | ```javascript
880 | const data = [
881 | {a: 'happy', b: 'robin', c: ['blue','green']},
882 | {a: 'tired', b: 'panther', c: ['green','black','orange','blue']},
883 | {a: 'sad', b: 'goldfish', c: ['green','red']}
884 | ];
885 |
886 | ```
887 |
888 | **Write a function to return all the unique colors from `data` as an array.** Hint: use the `flat` function from the above example.
889 |
890 |
891 | # ES6 and how Babel helps
892 | ## Babel
893 |
894 | * [What is Babel?](https://kleopetrov.me/2016/03/18/everything-about-babel/)
895 |
896 | >Babel is a highly configurable compiler that lets you use experimental JavaScript features and extensions, compiling down into older JavaScript versions that can be supported on a wider range of platforms. Of course, if a native platform doesn't support an ES2015 feature like Promise(), Babel won't fully be able to help -- but it can in many cases "polyfill" missing APIs to provide this functionality.
897 | * [React Express Tutorial](http://www.react.express/modern_javascript)
898 |
899 | >ECMAScript is the language specification used to implement the JavaScript language. Nearly every JavaScript environment today can run at least ECMAScript 5 (ES5), the version of JavaScript introduced in 2009. However, there are many new features in the latest versions of JavaScript that we'd like to use. Thanks to Babel, we can use them today! Babel transforms newer features into ES5 for cross-platform compatibility.
900 | * How to [set up Babel for react app](http://www.react.express/babel) or [set up Babel for node/express app](https://github.com/babel/example-node-server). For node app, assume you have this file structure:
901 |
902 | ```
903 | my-app
904 | ├───package.json
905 | ├───.babelrc
906 | ├───server
907 | │ ├───app.js <===ES6
908 | │ └───build
909 | | └───app.js <===ES5
910 | ...
911 | ```
912 |
913 | Add the following to `.babelrc`
914 |
915 | ```
916 | {
917 | "presets": [
918 | "env",
919 | "stage-2"
920 | ],
921 | "plugins": [
922 | "transform-runtime"
923 | ]
924 | }
925 |
926 | ```
927 | Add the following to `package.json`:
928 |
929 | ```
930 | "scripts": {
931 | "build": "babel server/app.js -o server/build/app.js",
932 | "start": "nodemon server/app.js --watch server --exec babel-node",
933 | "server": "nodemon server/server.js --watch server/app.js --exec babel-node"
934 | }
935 | "dependencies": {
936 | "express": "^4.16.2",
937 | "webpack": "^3.10.0"
938 | },
939 | "devDependencies": {
940 | "babel-cli": "^6.26.0",
941 | "babel-core": "^6.26.0",
942 | "babel-loader": "^7.1.2",
943 | "babel-plugin-transform-runtime": "^6.23.0",
944 | "babel-preset-env": "^1.6.1",
945 | "babel-preset-react": "^6.24.1",
946 | "babel-preset-stage-1": "^6.24.1",
947 | "babel-preset-stage-2": "^6.24.1",
948 | "eslint": "^3.19.0",
949 | "nodemon": "^1.14.11",
950 | "webpack-dev-middleware": "^2.0.4",
951 | "webpack-hot-middleware": "^2.21.0"
952 | }
953 |
954 | ```
955 | In your terminal:
956 |
957 | ```
958 | $ npm install
959 | $ mkdir server/build
960 | $ npm run build
961 | $ npm run start
962 | ```
963 |
964 | In `package.json`, the following `build` script is saying compile the entire server directory and output it to the server/build directory. `-d` means directory.
965 |
966 | ```
967 | "build": "babel server -d ./server/build"
968 |
969 | ```
970 | If we didn't have the `.babelrc` then we have to make this the build script:
971 | ```
972 | "build": babel server/app.js -o server/build/app.js --presets env,stage-2",
973 | ```
974 | If we didn't have the scripts in `package.json`, then every time we make a change to `server.js`, we would have to transpile the code from ES6 to ES5 and manually run the babel transpiling command to populate the build folder then run the ES5 version of the folder.
975 |
976 | ```
977 | $ babel babel server/app.js -o server/build/app.js --presets env,stage-2"
978 | $ nodemon server/app.js --watch server --exec babel-node
979 | ```
980 |
981 | ### Resources
982 |
983 | * [Free javascript books](https://jsbooks.revolunet.com/)
984 | * `babel-preset-es2015` is deprecated. Use `babel-preset-env` instead. [Read about it here](http://babeljs.io/env). `babel-preset-env` node [not working](https://github.com/facebookincubator/create-react-app/issues/1125) in create-react-app
985 | * [set up](https://babeljs.io/docs/plugins/transform-runtime/) `babel-runtime`, which "externalise references to helpers and builtins, automatically polyfilling your code without polluting globals.
986 | * [Christophe Coenraets's Tutorial](http://ccoenraets.github.io/es6-tutorial/setup-babel/)
987 | * [The most popular javascript links of 2017](https://medium.com/dailyjs/the-most-popular-javascript-links-of-2017-e4616e8b48c7)
988 | * [Modern JS Cheatsheet](https://github.com/mbeaudru/modern-js-cheatsheet) 😍
989 | * [Wearhive's List Of Best Practices for JavaScript Projects](https://github.com/wearehive/project-guidelines#readme) 😍
990 | * [Airbnb's JavaScript Style Guide](https://github.com/airbnb/javascript) 😍
991 | * [How JavaScript Works: Memory Management + How to Handle Four Common Memory Leaks](https://blog.sessionstack.com/how-javascript-works-memory-management-how-to-handle-4-common-memory-leaks-3f28b94cfbec)
992 | * [Tricky Closure Inteview Question](https://medium.com/coderbyte/a-tricky-javascript-interview-question-asked-by-google-and-amazon-48d212890703)
993 | * [JavaScript Closure Questions](https://coderbyte.com/algorithm/3-common-javascript-closure-questions)
994 | * [Three Questions to watch out for in JavaScript Interview](https://medium.freecodecamp.org/3-questions-to-watch-out-for-in-a-javascript-interview-725012834ccb)
995 | * [Making Functional Programming Click](https://hackernoon.com/making-functional-programming-click-836d4715baf2) 😍
996 | * [Coders At Work](http://one-shore.com/aaron/books/coders-at-work.pdf)
997 | * [97 things every programmer should know](file:///Users/xiaoyun/Downloads/97_Things_Every_Programmer_Should_Know.pdf)
998 | * [Testing in ES6 with Mocha and Babel 6](http://jamesknelson.com/testing-in-es6-with-mocha-and-babel-6/)
999 |
1000 | ## TODO
1001 | - [ ] Add javascript date function cheatsheet (see [react-native-travel-app](https://github.com/xiaoyunyang/react-native-travel-app) for the code)
1002 | - [ ] Add date functions.
--------------------------------------------------------------------------------
/guides/git-tutorial.md:
--------------------------------------------------------------------------------
1 | # Github / Git Tutorial
2 |
3 | #### This is a tutorial for Unix and Git newbies.
4 |
5 | ### Assume:
6 | * userA, userB, and userC all setup their computers with a Github account.
7 |
8 | ### Suppose:
9 | * userA wants to create an original repo called `ProjectName`.
10 | * userB wants to fork the `ProjectName` repo from usernameB.
11 | * userC wants to fork the `ProjectName` repo from userB.
12 |
13 | ## Git Tutorial For userA
14 | Go to https://github.com/`userA`/ and click the "New" button. Name the new repo `project-name`.
15 |
16 | 1. On your computer, go to terminal and `cd` into the directory you want to host the local repo, then do:
17 |
18 | ```
19 | $ git clone https://github.com/userA/project-name.git
20 | ```
21 | 2. Check that you have remote:
22 |
23 | ```
24 | $ git remote
25 | origin
26 | ```
27 | 3. Open the project in finder and in atom to edit the content of the folder.
28 |
29 | ```
30 | $ open .
31 | $ atom .
32 | ```
33 |
34 | Alternatively...
35 |
36 | On your computer, in Finder, make a new folder called `project-name`. Copy all the files you want to the `ProjectName` folder.
37 |
38 | In the Terminal, do the following:
39 |
40 | 1. Type `cd` into the terminal then drag the `project-name` folder into the terminal. You’ll see `directoryPath` being auto-completed in Terminal.
41 |
42 | `$ cd directoryPath`
43 |
44 | 3. Initialize the `project-name` folder as a git repo. This essentially makes this folder a "local git repo".
45 |
46 | `$ git init`
47 |
48 | 4. Link your "local git repo" to a "remote git repo" that you own. Call this remote git repo `origin`.
49 |
50 | ```
51 | $ git remote add origin ssh://git@github.com/userA/project-name.git
52 | ```
53 |
54 | 5. Make sure `origin` is an available remote and check the path.
55 |
56 | ```
57 | $ git remote
58 | # git remote -v
59 | ```
60 |
61 | 5. Sync your local repo to your remote repo.
62 |
63 | ```
64 | $ git fetch origin
65 | $ git add --all
66 | $ git commit -m 'Initial Commit!'
67 | $ git push origin master
68 | ```
69 |
70 | Note, if you added a LICENSE file or a README file from Github, make sure to do a `git pull origin master` before you do a `git add --all`.
71 |
72 | 7. Now open a file within `ProjectName` in [Atom](https://atom.io/) or another text editor. Make some changes to the code. To sync your local repo with your remote repo, do this:
73 |
74 | ```
75 | $ git fetch origin
76 | $ git add --all
77 | $ git commit -m 'I made some changes!'
78 | $ git push origin master
79 | ```
80 |
81 | 6. After you accept a pull request from userB, your remote repo is updated. Now you want to sync your local repo with your remote repo:
82 |
83 | $`git pull origin master`
84 |
85 |
86 |
87 |
88 | ## Git Tutorial For userC
89 | Go to https://github.com/`userB`/`project-name` and click the "Fork" button.
90 |
91 | In the Terminal, do the following:
92 |
93 | 1. Type `cd` into the terminal and drag and drop the folder where you want to create the project folder from Finder into Terminal. You’ll see directoryPath being auto-completed in Terminal.
94 |
95 | `$ cd directoryPath`
96 |
97 | 2. Make a new folder called `project-name`.
98 |
99 | `$ mkdir project-name`
100 |
101 | 3. Go into the `project-name` folder
102 |
103 | `$ cd project-name`
104 |
105 | 4. Initialize the `project-name` folder as a git repo. This essentially makes this folder a "local git repo".
106 |
107 | `$ git init`
108 |
109 | 5. Link your "local git repo" to a "remote git repo" that you own. Call this remote git repo `origin`.
110 |
111 | `$ git remote add origin ssh://git@github.com/userC/project-name.git`
112 |
113 | 6. Populate the `project-name` folder on your computer (i.e., local repo) with the files from the remote repo's master branch.
114 |
115 |
116 | `$ git pull origin master`
117 |
118 | 7. List the files in your `project-name` folder to make sure the pull was successful. You should see this folder populated with files downloaded from the remote repo
119 |
120 | `$ ls`
121 |
122 | 8. Link your "local git repo" to another remote git repo that userB owns. Recall you forked the `project-name` repo from userB. The upstream user's (i.e., userB) repo. Call this `upstream`.
123 |
124 | `$ git remote add upstream https://github.com/userB/project-name`
125 |
126 | 9. Make sure `origin` and `upstream` are both available remote.
127 |
128 | `$ git remote`
129 |
130 | 10. Now open a file within `project-name` in [Atom](https://atom.io/) or another text editor. Make some changes to the code. To sync your local repo with your remote repo, do this:
131 |
132 | ```
133 | $ git fetch origin
134 | $ git add --all
135 | $ git commit -m ‘I made some changes!'
136 | $ git push origin master
137 | ```
138 |
139 | 11. To sync your local repo with userB's repo, do the following:
140 |
141 | `$ git pull upstream master`
142 |
143 |
144 |
145 | ## Other Useful Commands
146 | Some useful things you can do when things go haywire or just to get the most usefulness out of git:
147 |
148 | 1. Revert your local repo to the previously committed version when everything still worked:
149 |
150 | ```
151 | $ git log
152 |
153 | # git will display the following:
154 | # commit:
155 | # ...
156 |
157 | # type q to exit the log
158 | :
159 |
160 | # force your local to the commitID
161 | $ git reset --hard
162 |
163 | # force your remote to the commitID
164 | $ git push --force origin master
165 |
166 | ```
167 |
168 | 2. Switching between branches:
169 |
170 | ```
171 | # checkout the alias of the remote e.g., origin
172 | $ git remote -v
173 |
174 | # switch to a new branch called boilerplate
175 | $ git checkout -b boilerplate
176 |
177 | # look at all your branches
178 | $ git branch
179 | # you should see git display the following branches for origin:
180 | # b1 = master and b2 = boilerplate
181 |
182 | # push local repo to boilerplate branch
183 | $ git push origin boilerplate
184 |
185 | ```
186 | 3. Your local repo should never go out of sync with your remote repo. Git prevents you from pushing changes from your local repo to your remote repo if there are changes in your remote repo that you don't have locally. If you don't want to sync with your local repo with the remote and you just want to overwrite the remote repo with whatever you have locally, this is a useful command:
187 |
188 | ```
189 | $ git push origin master --force
190 | ```
191 |
192 |
193 | 4. If you accidentally initiated a directory as a git repo, this undos the `git init`:
194 |
195 | ```
196 | $ rm -rf .git
197 | ```
198 |
199 | 5. If you don't want to have to enter your password everytime when you push to a remote, then in the project local repo, do the following:
200 |
201 | * Per [**the official guide from Github**](https://help.github.com/articles/changing-a-remote-s-url/), you want to switch your remote URLs from SSH to HTTPS:
202 |
203 | ```
204 | $ git remote set-url origin https://github.com/USERNAME/REPOSITORY.git
205 | ```
206 |
207 |
208 | ## Notes on .gitignore
209 | The `.gitignore` file should be included in your local repo folder, which tells git to not add files and folders that you don't want to share publically on Github to your remote repo. What kind of files are these?
210 |
211 | * `DS_Store` and other metadata files that macOS create
212 | * `.env` files which includes configuration for your application that may include secret keys that you don't want people to know about.
213 | * Transient files from your working directory that aren't useful to other collaborators, such as compilation products, temporary files IDEs create, etc. Prime example is the `node_modules` which tend to be large and people downloading your project can get from running `npm install` if they have the right dependencies listed in `package.json`.
214 |
215 | In general, you should include the following in your `.gitignore`
216 |
217 | ```
218 | #.gitignore
219 |
220 | lib-cov
221 | *.seed
222 | *.log
223 | *.csv
224 | *.dat
225 | *.out
226 | *.pid
227 | *.gz
228 | *.swp
229 |
230 | pids
231 | logs
232 | results
233 | tmp
234 | coverage
235 |
236 | # API keys
237 | .env
238 | auth.js
239 |
240 | # Dependency directory
241 | node_modules
242 | bower_components
243 | build
244 |
245 | # Editors
246 | .idea
247 | *.iml
248 |
249 | # OS metadata
250 | .DS_Store
251 | Thumbs.db
252 |
253 | ```
--------------------------------------------------------------------------------
/guides/react-notes.md:
--------------------------------------------------------------------------------
1 |
2 | [JSX](http://www.react.express/jsx)
3 | >JSX is a shortcut for using the `React.createElement()` API, that is much more concise, easy to read, and visually looks a little like the generated UI (as both are tree-like).
4 |
5 | >JSX is tag-based like XML. Each tag, like ``, is transformed into a call to `React.createElement()`. Any attributes become props of the instantiated component.
6 |
7 | ```javascript
8 | // JSX
9 | const a =
10 |
11 | const b = (
12 |
15 | 42
16 |
17 | )
18 |
19 | // Javascript equivalent
20 | var a = React.createElement('div', null);
21 |
22 | var b = React.createElement(
23 | 'div',
24 | {
25 | foo: 'hello',
26 | bar: baz },
27 | React.createElement(
28 | 'span',
29 | null,
30 | '42'
31 | )
32 | );
33 | ```
34 |
35 | There are two libraries we'll use:
36 |
37 | * `react` contains the APIs for creating components
38 | * `react-dom` contains the APIs for rendering to the browser DOM
39 |
40 | [React Updating Cycles](http://www.react.express/lifecycle_api) and `class` vs `function`
41 |
42 | * For simple React components, we can use a function. For example:
43 |
44 | ```javascript
45 | import React from 'react'
46 | import { render } from 'react-dom'
47 |
48 | const node = document.querySelector('#app')
49 | const element =
Hello World!
50 |
51 | render(element, node)
52 | ```
53 |
54 | * Often we want to render more complex components which encapsulate logic, styles, and multiple DOM components, and use lifecycle events (e.g. `componentWillMount`) and set any states. In this case, we want to use should use `class`.
55 |
56 | ```javascript
57 | import React, { Component } from 'react'
58 | import { render } from 'react-dom'
59 |
60 | class Counter extends Component {
61 |
62 | state = {count: 0}
63 |
64 | componentDidMount() {
65 | setInterval(() => {
66 | this.setState({count: this.state.count + 1})
67 | }, 1000)
68 | }
69 |
70 | render() {
71 | const {count} = this.state
72 | const {color, size} = this.props
73 |
74 | return (
75 |
97 | )
98 | }
99 | }
100 |
101 | render(, document.querySelector('#app'))
102 | ```
103 |
104 | * If you use `class`, [make sure](http://cheng.logdown.com/posts/2016/03/26/683329) to call `super()` if you have a constructor.
105 |
106 | > ES6 class constructors MUST call `super()` if they are subclasses. Thus, you have to call `super()` as long as you have a constructor. (But a subclass does not have to have a constructor)
107 |
108 | ```javascript
109 |
110 | import React, { Component } from 'react'
111 | import { render } from 'react-dom'
112 |
113 | // OK
114 | class MyClass extends Component {
115 | render(){
116 | return
Hello { this.props.world }
;
117 | }
118 | }
119 |
120 | // OK
121 | class MyClass extends React.component{
122 | constructor(props){
123 | super(props);
124 | console.log(this.props); // this.props is undefined
125 | }
126 | }
127 |
128 | // OK
129 | class MyClass extends React.component{
130 | render(){
131 | // There is no need to call `super(props)` or even having a constructor
132 | // this.props is automatically set for you by React
133 | // not just in render but another where else other than the constructor
134 | console.log(this.props); // it works!
135 |
136 | }
137 | }
138 | ```
139 |
140 | In summary:
141 |
142 | * Calling `super()` is necessary if you need to have a `constructor`.
143 | * Calling `super(props)` is necessary if you want to access `this.props` inside the `constructor`
144 | * ES6 class constructors MUST call `super()` if they are subclasses; however a subclass does not have to have a constructor.
145 |
146 |
147 | According to the [Official Documentation](https://reactjs.org/docs/react-component.html#constructor)
148 | > The `constructor` for a React component is called before it is mounted. When implementing the `constructor` for a `React.Component` subclass, you should call `super(props)` before any other statement. Otherwise, this.props will be undefined in the constructor
149 |
150 | >The `constructor` is the right place to initialize state. To do so, just assign an object to this.state; don’t try to call `setState()` from the constructor. The constructor is also often used to bind event handlers to the class instance.
151 |
152 | >If you don’t initialize state and you don’t bind methods, you don’t need to implement a constructor for your React component.
153 |
154 | Note, The difference between `constructor` and `getInitialState` is the difference between ES6 and ES5 itself. `getInitialState` is used with React.createClass and `constructor` is used with `React.Component`.
155 |
156 | ```javascript
157 | import React, { Component } from 'react'
158 | import { render } from 'react-dom'
159 | class MyClass extends React.component{
160 | constructor(props) {
161 | super(props);
162 | this.handleChange = this.handleChange.bind(this);
163 | this.state = {
164 | color: props.initialColor
165 | }
166 | }
167 | handleChange(e) {
168 | this.setState({temperature: e.target.value});
169 | }
170 | render() {
171 | // ...
172 | }
173 |
174 | }
175 |
176 | ```
177 | Beware of this pattern, as state won’t be up-to-date with any props update. Instead of syncing props to state, you often want to [lift the state up](https://reactjs.org/docs/lifting-state-up.html) instead.
178 | > Often, several components need to reflect the same changing data. We recommend lifting the shared state up to their closest common ancestor. Let’s see how this works in action.
179 |
180 | **TL;DR** You want to make children render `this.props` instead of `this.state` and have the parent pass a function (say `changeParentProps` which modifies its states, to the chilren so the children can call `onClick={this.props.changeParentProps}` in their render functions.
181 |
182 |
183 | [Styling React Component](http://www.react.express/styling) - Three ways:
184 |
185 | 1. Inline Styles
186 | * Pro: No libraries/dependencies), dynamic (variables, themes, merging, etc) and works on Works on every React renderer (web, native, etc)
187 | * Con: No CSS features (psuedoclasses, media queries, keyframe animations) out of the box.
188 | 2. CSS and Class Names
189 | * Simply write CSS using any pre-processor or post-processor you'd like (LESS, Sass, Stylus, PostCSS), and use the className attribute of your components to apply styles. With this option, you can have many of the CSS features for dynamic styles - pseudo classes (`:hover`), media queries, keyframe animations, etc.
190 |
191 |
192 | [Event Handling](http://www.react.express/event_handling)
193 |
194 | ```javascript
195 | // Bad practice
196 |
197 | import React, { Component } from 'react'
198 | import { render } from 'react-dom'
199 |
200 | class CounterButton extends Component {
201 |
202 | state = {count: 0}
203 |
204 | render() {
205 | const {count} = this.state
206 |
207 | return (
208 |
211 | )
212 | }
213 | }
214 |
215 | render(, document.querySelector('#app'))
216 | ```
217 | >It's generally bad practice to define functions within the props of your React elements like we did in the previous example. This is because a new function will be created each time `render` is called - it's common for components to compare props using `===`, which in this case will indicate that the `onClick` prop of the button has changed, and may cause unnecessary re-renders. Using .bind within component props has a similar effect.
218 |
219 | ```javascript
220 | // Better
221 |
222 | import React, { Component } from 'react'
223 | import { render } from 'react-dom'
224 |
225 | class CounterButton extends Component {
226 |
227 | state = {count: 0}
228 |
229 | handleClick = () => {
230 | const {count} = this.state
231 |
232 | this.setState({count: count + 1})
233 | }
234 |
235 | render() {
236 | const {count} = this.state
237 |
238 | return (
239 |
242 | )
243 | }
244 | }
245 |
246 | render(, document.querySelector('#app'))
247 |
248 | ```
249 |
250 | [Conditional Rendering](http://www.react.express/conditional_rendering)
251 |
252 | ```javascript
253 | // Rendering with &&
254 | {subtitle && (
255 |
313 | )
314 | }
315 | }
316 |
317 | ```
318 |
319 | [List and Keys](http://www.react.express/lists_and_keys)
320 |
321 | * Every React component can be passed a special prop called the `key`. React uses this `key` to determine the rendered element's identity. Understanding element identity is critical for performance and minimizing DOM manipulation: for example, if the first element in a list of thousands should no longer be rendered, React needs some way to detect this. Instead of re-rendering thousands of elements, React can simply remove a single DOM node for the first element, which is much more efficient.
322 | * if you wanted to, you could assign a key to every element. You can even force a component to re-render by assigning a different key (this tells React that the element's identity has changed, thus triggering a re-render). But most of the time, you don't need to consider keys because React takes care of them automatically. It's likely the only time you'll need to use them is when rendering lists of elements.
323 | * Ideally, we want to make the `key` the unique identifier for the items in the list (i.e., its actual value). If items in our data have no unique identifier of any kind, then we will generally resort to using the index of the item as its key. This silences the warning from React about forgetting to include keys, but remember that doing this will cause React to identify elements incorrectly if the data is modified
324 |
325 | ### Learning Resources
326 | **React**
327 |
328 | * Brad Westfall's [LearnReact Series](https://github.com/bradwestfall/Learn-React)
329 | * [React.Express Tutorial](http://www.react.express) - Learn about React, Redux, ES6, Babel, Webpack
330 |
331 | **React Router**
332 |
333 | * [react-router-config](https://www.npmjs.com/package/react-router-config)
334 | * [Starter project tutorial](https://www.mokuji.me/article/universal-app-react-router)
335 | * [Egghead Tutorial](https://egghead.io/lessons/react-create-basic-routes-with-the-react-router-v4-browserrouter)
336 | * [route-config example](https://reacttraining.com/react-router/web/example/route-config)
337 | * [A Simple Tutorial](https://medium.com/@pshrmn/a-simple-react-router-v4-tutorial-7f23ff27adf)
338 | * [Site Point Tutorial](https://www.sitepoint.com/react-router-v4-complete-guide/)
339 | * [Detailed Tutorial](https://blog.digitalkwarts.com/server-side-rendering-with-reactjs-react-router-v4-react-helmet-and-css-modules/)
340 | * [Lessons learned from migrating to v4 from an earlier version](https://webuild.envato.com/blog/a-real-word-story-of-upgrading-react-router-to-v4-in-an-isomorphic-app/)
341 | * [unofficial migration guide](https://codeburst.io/react-router-v4-unofficial-migration-guide-5a370b8905a).
342 | 5. [Read this](https://github.com/ReactTraining/react-router/pull/4934) for more on how to fix the deprecation warnings.
343 | > Failed Context Types: Calling PropTypes validators directly is not supported by the `prop-types` package
344 | * [Integrate React Router v4 with Server Router](https://crypt.codemancers.com/posts/2017-06-03-reactjs-server-side-rendering-with-router-v4-and-redux/)
--------------------------------------------------------------------------------