diff --git a/README.md b/README.md
index f9fef98..d5c17a7 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,5 @@
-# concepts
\ No newline at end of file
+# concepts
+
+> This repository has been deprecated.
+
+Formerly it served as the location for concepts in the student handbook, which was a separate repository. We found there wasn't any value in separating the content from the book so the concepts have been moved into the [student handbook](https://github.com/dev-academy-programme/book-source). Only the concepts being used at the time were migrated out of this repo.
diff --git a/agile/introduction.md b/agile/introduction.md
index a0c543f..b89dee0 100644
--- a/agile/introduction.md
+++ b/agile/introduction.md
@@ -1,7 +1,8 @@
-Agile is a methodology for software development whose aims include responsiveness, flexibility, and early/continuous delivery of products.
+# Agile Software Development
+Agile is a methodology for software development whose aims include responsiveness, flexibility, and early/continuous delivery of products.
-### Why?
+## Why?
Agile's origins date back to the 1970s. People started becoming frustrated with the traditional 'waterfall' model of development:
@@ -22,17 +23,17 @@ Trouble is, often what the finished product actually needs to be can't be determ
> At the end of a project, a team might have built the software it was asked to build, but, in the time it took to create, business realities have changed so dramatically that the product is irrelevant. In that scenario, a company has spent time and money to create software that no one wants. Couldn’t it have been possible to ensure the end product would still be relevant before it was actually finished? ~ [agilemethodology.org](https://agilemethodology.org)
-### Scrum
+## Scrum
Scrum is the most common/popular approach to Agile development. You can read more about it on Wikipedia. Some people use the terms interchangeably, but strictly speaking Scrum is _a kind_ of Agile. Another way to describe it: Scrum is a _framework_ for Agile development. It gives specific guidance on roles (Product Owner, Scrum Master) and the process or order of events. Most of the following content is related to "Scrum-flavoured Agile".
-### Team composition
+## Team composition
Traditional teams are often siloed: all the management/architects together, all the designers together, all the developers together, all the testers together. Agile development encourages teams to be _cross-functional_: made up of people from many different disciplines. Scrum encourages self-organising teams.
-### Iteration
+## Iteration
In Agile, we try to incorporate a little of each phase of development (requirements, design, develop, etc) into short cycles, often called _sprints_. The idea is to have code that could potentially be _shipped_ (deployed, published) at the end of each sprint. Two week sprints are common.
@@ -40,19 +41,19 @@ In Agile, we try to incorporate a little of each phase of development (requireme
[Source](https://commons.wikimedia.org/wiki/File:Agile_Project_Management_by_Planbox.png)
-### The backlog
+## The backlog
A backlog is a list of tasks that together make up an application: if you completed all of them, you'd have a great product! Some are product features, but not all: documentation and bug fixes are also entered on the backlog. Items on the backlog may be further classified with labels: is it a feature or a bug? Is it considered part of the Minimum Viable Product? Is it frontend or backend, or both?
The backlog is likely to feature _user stories_, and may break each story into multiple tasks to be completed.
-### Sprint planning
+## Sprint planning
At the start of each sprint, a [meeting](http://www.leadingagile.com/2012/08/simple-cheat-sheet-to-sprint-planning-meeting/) is held to set the scope of the sprint, deciding which tasks will be completed by the end of it.
-### Stand-up
+## Stand-up
Held daily, the stand-up (or "scrum") should be carefully timeboxed and starts even with missing team members. Everybody should report:
@@ -63,19 +64,19 @@ Held daily, the stand-up (or "scrum") should be carefully timeboxed and starts e
This isn't the time for long discussions! Standups are for quick summaries. For most teams they shouldn't take longer than 15 minutes. A scrum master or similar role will keep track of blocks that might affect the ability of the team to deliver on time, and who on the team is assigned to resolve the block.
-### Sprint review
+## Sprint review
Review the work that was completed, and what was not completed. Demo the working code. Don't demo what was not completed!
-### Sprint retrospective
+## Sprint retrospective
What went well? What could we do differently or better next time?
This is a great chance to learn from the previous weeks. It should not be used as an opportunity to cast _blame_, however. Instead, identify _systemic_ problems. How could our team improve to overcome the difficulties we experienced?
-### Resources
+## Resources
- http://agilemethodology.org/
- http://scrumreferencecard.com/
diff --git a/agile/user-stories.md b/agile/user-stories.md
deleted file mode 100644
index 3bf88f3..0000000
--- a/agile/user-stories.md
+++ /dev/null
@@ -1,20 +0,0 @@
-One way to represent a feature you'd like your program to have is the [user story](https://manifesto.co.uk/agile-concepts-user-stories/). This is a formulaic description of a 'want' that the user has.
-
-
-### Format
-
-User stories follow a distinct format:
-
-> As a _[ persona ]_ I want _[ feature ]_ so that I can _[ justification ]_.
-
-Some examples:
-
- * As a user I want to login with username and password so that I can access my information.
- * As a user I want to login with Facebook so that I don't have to remember another password.
- * As a user I want to change my profile picture because I don't look like that anymore.
- * As an administrator I can view a list of users so that I can manage my site.
-
-
-### Why?
-
-User stories divide our programs into discrete 'chunks' that can easily be worked on separately. They help us understand and manage the _scope_ and priority of our work: which features we should add next, and which are _must have_ as opposed to _nice to have_. They also help us keep the end user in mind: you know, that person we're actually developing all this for!
diff --git a/ajax/ajax-intro.md b/ajax/ajax-intro.md
deleted file mode 100644
index 0bb836d..0000000
--- a/ajax/ajax-intro.md
+++ /dev/null
@@ -1,3 +0,0 @@
-In the browser these are often called AJAX, or XHR.
-
-It's easy to issue HTTP requests to other sites, but if the site the page came from doesn't have the same domain name as the site you're calling, you'll hit the limitations of [Cross-origin Request Sharing (CORS0](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS) unless you're making requests to an API that explicitly allows it.
diff --git a/ajax/cors.md b/ajax/cors.md
deleted file mode 100644
index 6d14b97..0000000
--- a/ajax/cors.md
+++ /dev/null
@@ -1,9 +0,0 @@
-A resource makes a cross-origin HTTP request when it requests a different type of resource from a different domain. For example, an HTML page served from http://accio.com makes an src request for http://lumos.com/light.jpg. Many pages on the web today load resources like CSS stylesheets, images and scripts from separate domains; such as the [jQuery](https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-rc1/jquery.js) or [normalise](https://cdnjs.cloudflare.com/ajax/libs/normalize/4.1.1/normalize.css) CDN.
-
-For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. So, a web application using XMLHttpRequest could only make HTTP requests to its own domain.
-
-To get around this, on both the server and the request we have to explicitly state what type of requests and data we expect. CORS is a way to work safely within Cross Origin Resouce Sharing. CORS gives web servers cross-domain access controls, which enable secure cross-domain data transfers. Modern browsers use CORS in an API container - such as XMLHttpRequest - to mitigate risks of cross-origin HTTP requests.
-
-There are some good examples of this in action on the W3 page [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS) or another one [here](http://www.html5rocks.com/en/tutorials/cors/)
-
-Within the wonderful world of express.js, we can set what content we expect in our servers using this fabulous and easy to use module, [npm cors](https://www.npmjs.com/package/cors) (other modules are available!)
diff --git a/api/api-proxy.jpg b/api/api-proxy.jpg
deleted file mode 100644
index fccefbc..0000000
Binary files a/api/api-proxy.jpg and /dev/null differ
diff --git a/api/cors.md b/api/cors.md
deleted file mode 100644
index 2d1b2cb..0000000
--- a/api/cors.md
+++ /dev/null
@@ -1,21 +0,0 @@
-Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources (e.g. fonts) on a web page to be requested from another origin outside the domain from which the first resource was served. For example, if our web app hosted at https://blog.foo.com and in our `index.html` page we have ``, that image (a resource) is considered be shared cross-origin. Some resources are not considered _restricted_. A web page may freely embed cross-origin images, stylesheets, scripts, iframes, and videos. Certain "cross-origin" requests, notably Ajax requests (web API calls), however are forbidden by default by the [same-origin security policy](https://en.wikipedia.org/wiki/Same-origin_policy). The same-origin security policy is a feature of web browsers that prevent a web page from one origin to run scripts from a different origin.
-
-
-### What defines an origin?
-
-The origin of a resource is defined by its URL. Specifically, the part of the URL before the first folder or file. Here are some examples of cross-origin and same-origin URLs:
-
-* http://foo.com and https://foo.com: **cross-origin** because of different [URI schemes](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) (http/https)
-* http://www.foo.com and http://blog.foo.com: **cross-origin** because of different [hostnames](https://en.wikipedia.org/wiki/Hostname) (www/blog)
-* http://foo.com:3000 and http://foo.com:8080: **cross-origin** because of different [ports](https://en.wikipedia.org/wiki/Port_(computer_networking)) (3000/8080)
-* http://foo.com and http://bar.com: **cross-origin** because of different domain names (foo/bar)
-* http://foo.com/profile and http://foo.com/v1/users: **same-origin**
-
-
-### Configuring CORS
-
-CORS can only be configured on the server that provides the restricted resource. That means if we want to consume an API from the browser, and the URL of the API doesn't have the same origin as the page our script is running in, the server must be configured to allow requests from other origins. When a web API server has been configured to accept requests from other origins, it will include an `Access-Control-Allow-Origin` HTTP response header. As long as our client-side script came from a matching origin, we shouldn't be effected by the same-origin security policy.
-
-But what if we can't change the configuration on the server? That just means we can't consume the API from a web browser. That doesn't mean we can't consume the API from our server. We can route requests from our client via our server (we won't need a CORS setup if our client and server have the same origin) and get our server to hit other servers. Note that our server doesn't have same-origin constraint, because the primary reason for a same-origin constraint is to avoid scripts running within a browser to read or interfere with the browser's DOM. This illustrates the relationship and calling pattern of the client getting results from the external API via our server.
-
-
diff --git a/api/crud-rest.md b/api/crud-rest.md
deleted file mode 100644
index 49ee411..0000000
--- a/api/crud-rest.md
+++ /dev/null
@@ -1,30 +0,0 @@
- Resource action | Associated HTTP request
-:----------------|:------------------------
- **C**reate | `POST`
- **R**ead | `GET`
- **U**pdate | `PUT`
- **D**estroy | `DELETE`
-
-REST = Representational State Transfer
-
-
-### Example: managing users
-
-CRUD is a way of talking about the basic actions we might want to perform with users:
- - create a new user
- - see all the users
- - see a particular user
- - update a particular user
- - delete a particular user
-
-
- Resource action | Path/route | HTTP request | ?
-:----------------|:-----------|:-------------|------
- **C**reate | `/users` | `POST` | creates a new user with the parcel of data you have `POST`ed
- **R**ead | `/users` | `GET` | `GET` a list of all users
- **R**ead | `/users/5` | `GET` | `GET` the data of user 5
- **U**pdate | `/users/5` | `PUT` | update the date of user 5 with data you have `PUT`
- **D**estroy | `/users/5` | `DELETE` | `DELETE` / destroy user 5
- | `/users/new`| `GET` | `GET` the form for creating a new user
- | `/users/5/edit` | `GET` | `GET` the form for editing a new user
-
diff --git a/api/intro.md b/api/intro.md
index 27eed92..611fdc8 100644
--- a/api/intro.md
+++ b/api/intro.md
@@ -1,4 +1,6 @@
-Application Programming Interface - not an initialism that feels particularly useful.
+# Application Programming Interface
+
+Admittedly not an initialism that feels particularly useful.
Essentially, an API is a point where you can access information if you ask for it in a specific manner.
@@ -15,3 +17,4 @@ If we ask the bank teller through the window (*endpoint*) 'Hey, can I have $300?
Imagine if you will, you go to the bank window (*endpoint*) wearing a mask, waving a toy gun around and shouting 'GIVE ME ALL THE MONEY!' You are not going to get any money (if the bank's security is sufficiently strong!)
This highlights one of the most important features of using an API: there will be a specific way in which you can interact with them, which will be listed in its documentation. If you don't ask an API for information in a way it expects, you will not get your required data.
+
diff --git a/api/keys.md b/api/keys.md
deleted file mode 100644
index 440a5ae..0000000
--- a/api/keys.md
+++ /dev/null
@@ -1,15 +0,0 @@
-It isn't uncommon when consuming an external web API that you'll need to authenticate your app in order to use it. Often this authentication doesn't need a high security solution; for example when accessing non-sensative read-only data. In these cases, we only need to send a string that identifies our app. We call this string a _key_. We usually get this key from the admin section of our developer user account on the site. In the case of [mashape.com](https://mashape.com), we must send this key as the value of a `X-Mashape-Authorization` HTTP request header in each of our API calls.
-
-When using [`superagent`](https://github.com/visionmedia/superagent), we might make the request like this:
-
-```js
-request
- .get('https://numbersapi.p.mashape.com/1/22/date')
- .set('X-Mashape-Authorization', '7zdlxkb3jqmshIgOJzR0qN5NdQc3p1PxmhXjsnJvX4hNVr2Yio')
- .set('Accept', 'application/json')
- .end(function(err, res){
- console.log(res.body.text)
- })
-```
-
-This does require you to send your API key to the browser, which yes, means anyone can see your key and potentially use it. It also means you're probably commiting the key to your source control repository. In low security scenarios this can be okay. We will explore more secure scenarios later in the bootcamp, but what if you don't want to include your key in the client-side code even in low security scenarios? In this case you will need to consume the API from a server, your own API. Doing so will keep the key out of source control and away from any browsers. If you take this approach, consider using [`dotenv`](https://www.npmjs.com/package/dotenv) as a place to keep your API key. You'll place the key in a `.env` file and make sure this file has an entry in your `.gitignore` file. The npm package is smart enough to use the contents of the `.env` file when it can find it, and use normal environment variables when it can't...
diff --git a/api/supertest.md b/api/supertest.md
deleted file mode 100644
index d93ad04..0000000
--- a/api/supertest.md
+++ /dev/null
@@ -1,36 +0,0 @@
-[Supertest](https://www.npmjs.com/package/supertest) is a great way to test APIs. The way you use it is quite similar to [Superagent](https://www.npmjs.com/package/superagent).
-
-Here's some example usage, which incorporates tape.
-
-```js
-var request = require('supertest')
-var test = require('tape')
-
-var app = require('../app.js')
-
-test('/users route returns an object containing an array of users', function (t) {
- // Arrange
- var expected = true
-
- // Act
- request(app)
- .get('/users')
- .expect('Content-Type', /json/)
- .expect(200)
- .end(function (err, res) {
- // Assert
- t.equal(err, null)
- t.equal(Array.isArray(res.body.users), expected)
- t.end()
- })
-})
-
-// Close any open connections
-test.onFinish(function () {
- process.exit(0)
-})
-```
-
-Here Supertest is using its API testing tools (`expect`) to check the headers and HTTP status code it receives from its GET request to `/users`. It gives us the response to test in `.end()`. The test checks several things: first, that no error was returned; second, that there is a property named `users` on the response body, and that it is an array.
-
-We can't test the exact content being returned from the route because it could be different each time. We'd have to have the exact same database records every time we ran the test to ensure predictable behaviour. Tests that examine a route in this way are often referred to as _integration tests_, because they use multiple parts of the system (the database, network and filesystem in particular) which are not [mocked](https://en.wikipedia.org/wiki/Mock_object#Use_in_test-driven_development).
diff --git a/api/versioning.md b/api/versioning.md
index 6c6431d..1d576dd 100644
--- a/api/versioning.md
+++ b/api/versioning.md
@@ -1,7 +1,6 @@
-APIs should be properly versioned.
-APIs evolve and change, we must do this while supporting old versions.
-Otherwise, if you just change your API, a lot of your clients would be in trouble.
-Although, we won't be developing multiple versions (today we're working on V1), it is important that we plan for the future and properly namespace our documentation and work under V1 namespace.
+# Versioning APIs
+
+APIs should be properly versioned. APIs evolve and change, we must do this while supporting old versions. Otherwise, if you just change your API, a lot of your clients would be in trouble. Although, we won't be developing multiple versions (today we're working on V1), it is important that we plan for the future and properly namespace our documentation and work under V1 namespace.
Here's our v2 api: get a list of all cats at `/cats`
@@ -15,4 +14,5 @@ The original route for getting all the cats was `/show_me_the_cats`
```
api/v1/show_me_the_cats
-```
\ No newline at end of file
+```
+
diff --git a/api/web-apis.md b/api/web-apis.md
deleted file mode 100644
index 2ebf0e4..0000000
--- a/api/web-apis.md
+++ /dev/null
@@ -1,49 +0,0 @@
-Web APIs are interfaces for other applications instead of users. They don't have a visual interface - only data. We often refer to these blocks of data returned from web APIs as _resources_. A resource maps very closely to what you understand as a database entity/table, a type of thing you are storing.
-
-
-## REST and JSON
-
-REST stands for Representational State Transfer and was coined by Roy Fielding in his PhD dissertation titled [Architectural Styles and the design of Network-based Software Architectures](https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm). Chapter 5 describes stateless entities (what we're storing in our database) as resources. It also describes how we can refer to these resources using a uniform indicator: the URL. This is why you will see URLs describe individual resources like this: `/widgets/213/characteristics`.
-
-JSON, JavaScript Object Notation, is a string representation for JavaScript objects. We can use `JSON.stringify(jsObj)` to convert (serialise) a JavaScript object to a string, and `JSON.parse(jsonString)` to convert (deserialise) a JSON string back to a JavaScript object. Fortunately, Express.js can do this for us as we'll see below. This is the recommended (and most common) format for REST API requests and responses.
-
-
-## Exposing web API routes
-
-Routes are exposed for web APIs in the same way they are for routes that return other web assets. The main difference is they accept and respond with JSON.
-
-There are a few different things you should notice about the code samples below. The endpoints they define use an `:id` syntax and `req.params` rather than `req.query` we've seen before. Using route params is more explicit and much more common with REST web APIs.
-
-### Returning JSON
-
-We use `res.json` to return JSON to the caller:
-
- ```js
- // server.js
- var widgets = require('./routes/widgets')
- app.use('/widgets', widgets)
-
- // routes/widgets.js
- var express = require('express')
- var router = express.Router()
-
- router.get('/:id', function (req, res) {
- var id = req.params.id
- res.json({id: id, name: 'Best widget'})
- })
-
- module.exports = router
- ```
-
-Notice how it just uses a normal JavaScript object. The `.json()` method will take care of serialising the object to JSON.
-
-Don't forget Express.js is also capable of receiving JSON in the request body using the `body-parser` middleware module. This is common when using the POST and PUT verbs to insert and update resources.
-
-```js
-// server.js
-var express = require('express')
-var bodyParser = require('body-parser')
-var app = express()
-app.use(bodyParser.json())
-```
-
diff --git a/architecture-patterns/mvc-intro.md b/architecture-patterns/mvc-intro.md
deleted file mode 100644
index 1c41b3d..0000000
--- a/architecture-patterns/mvc-intro.md
+++ /dev/null
@@ -1,10 +0,0 @@
-Building database-driven web applications requires a lot of moving parts: the server, views, routes, data access code, etc. For your application to be maintainable, it's very important to adhere to the _Single Responsibility Principle_ by putting each of these responsibilities in their own modules (files).
-
-Model-View-Controller (MVC) is one of the most common _separated presentation_ patterns. These patterns describe how to structure code according to the Single Responsibility Principle.
-
-**Model** is the data representation we apply to our templates. This is the second parameter we've been passing to templates with `res.render('view', model)`. We've also called it a _view model_ because this model is built specifically for a view.
-
-**View** is the visual representation part of the code - our templates. We've built these using HTML and Handlebars.
-
-**Controller** is the code that coordinates the interaction of the data (the model) and the view. We've been doing this in our `routes.js` file, but that often causes our routes to do too much. By creating a separate `controller.js` we can reduce the responsibility of our routes to get the view model from the controller, and apply it to the view.
-
diff --git a/architecture-patterns/orm-intro.md b/architecture-patterns/orm-intro.md
deleted file mode 100644
index 601f8b2..0000000
--- a/architecture-patterns/orm-intro.md
+++ /dev/null
@@ -1,3 +0,0 @@
-And object relational map a layer which helps you map data between different places.
-In the context of MVC, this is from your database to a model and back.
-Not all MVC frameworks have an ORM.
\ No newline at end of file
diff --git a/async/callback-hell.md b/async/callback-hell.md
deleted file mode 100644
index 8377c4d..0000000
--- a/async/callback-hell.md
+++ /dev/null
@@ -1,5 +0,0 @@
-When your asynchronous function calls another asynchronous function, which calls another asynchronous function, your callbacks can get quite nested.
-
-This anti-pattern can make your code very difficult to read and maintain.
-
-It's affectionately, and appropriately, known as called "[callback hell](http://callbackhell.com/)."
diff --git a/async/callbacks.md b/async/callbacks.md
deleted file mode 100644
index 71e9448..0000000
--- a/async/callbacks.md
+++ /dev/null
@@ -1,83 +0,0 @@
-A _callback_ is a function we pass to another function as a parameter. When the receiving function wants to send something _back_ to the first function, it _calls_ the callback.
-
-Remember `Array.map()`? It takes a callback function as a parameter:
-
-```js
-// Returns [2, 3, 4]
-[1, 2, 3].map(function (n) {
- return n + 1
-})
-```
-
-The anonymous function passed to `map` is called by `map`: we don't call it ourselves, we just tell it what to do once it gets called. This is a very common pattern in functional programming.
-
-
-## "Hello, Metaphorical Pizza?"
-
-We often use callbacks when working with _asynchronous functions_. An async function will go off and do its work, then call the callback you passed to it when it has some results to give you (or an error to report). In the meantime, the rest of your program continues on its merry way, not waiting for the operation to complete.
-
-Say you're hungry, and you order a pizza. You don't know ahead of time how long the pizza is going to take to arrive (30 min guarantees notwithstanding) and you're certainly not going to stand there doing nothing while you wait. You go on doing whatever you were doing, but you've provided your address to the pizza place so that when your order is ready, they can deliver it to you. They can also report an error: "We ran out of anchovies", or "The oven exploded".
-
-```js
-function deliver(err, pizza) {
- if (!err) {
- answerTheDoor()
- payFor(pizza)
- enjoy(pizza)
- }
-}
-
-orderAPizza('pepperoni', deliver)
-makeCoffee()
-callFriends()
-```
-
-In this example, `deliver` is a function being used as a callback. We immediately go on to doing other things after we've called `orderAPizza`, and the code inside the callback will only execute when the pizza place calls `deliver(null, pizza)`. (See below for why we used `null` here.)
-
-Async functions might take a little getting used to in the beginning, but you'll use them a _lot_ in your JavaScript programming and they will become second nature.
-
-
-## Reading from a file
-
-Node programs often pass callback functions that handle the data you expect to receive from APIs, from databases, or from the filesystem. The filesystem is an easily accessible way of practicing this technique.
-
-```js
-var fs = require('fs')
-
-fs.readFile('animals.txt', 'utf8', function (err, animals) {
- if (err) {
- console.error("Couldn't read file:", err.message)
- } else {
- console.log(animals)
- }
-})
-```
-
-This program reads a file from the directory in which it was run, and outputs the result to the terminal. Try it! When you're done, try modifying the string `'animals.txt'` to a filename you know _doesn't_ exist, and run the program again. You should see an error that Node can't open the file you asked for.
-
-The first thing to notice about this example is that everything interesting happens _inside the callback_. Remember, we're not making things happen ourselves: we're _defining_ what _will_ happen once `readFile` has finished its work: once it has either succeeded or failed to deliver the contents of the file.
-
-The next thing to notice is that the callback has a very particular structure. It's an _error-first callback_, a common convention in the Node world which assumes that the first parameter of the callback will always be either an error object or `null`. We should always check the error to make certain it's `null` before we try to use the `animals` parameter.
-
-This is a really common pattern in JavaScript programs. You'll be seeing it a lot, so get some practice in!
-
-
-## Named callbacks
-
-The callback doesn't have to be an anonymous function. It's often better to use a named function, both because it can be re-used and because it can be more readable:
-
-```js
-fs.readFile('birds.txt', 'utf8', displayFileContents)
-fs.readFile('trees.txt', 'utf8', displayFileContents)
-
-function displayFileContents (err, contents) {
- if (err) {
- console.error("Couldn't read file:", err.message)
- } else {
- console.log(contents)
- }
-})
-```
-
-Right away this makes our code a bit more DRY. We have to do the same thing with both files so why write the function twice? It can also make the code easier to debug since we only have to look in one location for the problem.
-
diff --git a/async/consuming-promises.md b/async/consuming-promises.md
deleted file mode 100644
index 9774a48..0000000
--- a/async/consuming-promises.md
+++ /dev/null
@@ -1,80 +0,0 @@
-Promises are another approach to asynchronous programming - one which conveniently allows us to sidestep callback-hell.
-
-Functions which perform asynchronous operations (such as interacting with the file system or a database) can return a promise which is **then** _resolved_ later. If that promise can't be kept (something is _rejected_) we can **catch** the error and deal with it.
-
-## `then` and `catch`
-
-```js
-getDataFromServer()
- .then(doSomethingWithData)
- .catch(handleError)
-```
-This example is about as simple as it gets. We don't need to understand the exact details of how to return a promise in order to use `getDataFromServer`. We just need to expect that:
-
-1. The `then` function will call `doSomethingWithData` if there is no error. `doSomethingWithData` can be passed a value.
-2. The `catch` function will call `handleError` if there is an error, and `handleError` will be passed an error (often a JavaScript `Error` object).
-
-It may be helpful to see the same code again using inline anonymous functions (though we should still try to use named functions for clarity):
-```js
-getDataFromServer()
- .then(function (data) {
- console.log(data)
- })
- .catch(function (err) {
- console.error(err)
- })
-```
-If `getDataFromServer` returns a _resolved_ promise, `then` will be called (and `catch` won't be). If it returns a _rejected_ promise, `catch` will be called (and `then` won't be).
-
-If you are familiar with callbacks, you'll notice it's like a callback that has had the `err` and the `data` handling parts separated. The same thing might be written like this with callbacks:
-
-```js
-getDataFromServer( function(err, data) {
- if (err) {
- console.error(err.message)
- return
- }
-
- console.log(data)
-})
-```
-
-## Promise chains
-
-We can also string together quite long 'promise chains' which define the order certain tasks should occur in:
-
-```js
-getDataFromServer()
- .then(checkTheData)
- .then(displayTheData)
- .then(modifyTheData)
- .then(saveTheData)
- .catch(handleError)
-```
-So long as each function in the chain returns a data object, this will help ensure everything takes place in the correct order. For example, `modifyTheData` would not be called before `checkTheData`.
-
-## Knex.js
-
-We can see this being put to work with the Knex library when accessing a database. A simple example: inserting a row, then querying the table and displaying the results.
-```js
-knex.insert({
- name: 'Daisy',
- age: 15
- })
- .into('dogs')
- .then(getNames)
- .then(showNames)
- .catch(displayError)
-
-function getNames () {
- return knex('dogs').select('dogs.name')
-}
-
-function showNames (names) {
- console.log(names)
-}
-
-function displayError (err) {
- console.error(err)
-}
-```
diff --git a/async/fs.md b/async/fs.md
deleted file mode 100644
index dc1c9d3..0000000
--- a/async/fs.md
+++ /dev/null
@@ -1,60 +0,0 @@
-Reading and writing files on the filesystem (the hard drive) is a common asynchronous operation. Node.js provides both synchronous and asynchronous functions to read and write files. You can see this in the documentation for [`readFile`](https://nodejs.org/api/fs.html#fs_fs_readfile_file_options_callback) (the async version) and [`readFileSync`](https://nodejs.org/api/fs.html#fs_fs_readfilesync_file_options) (the synchronous version). As you can see from the documentation for the [`fs`](https://nodejs.org/api/fs.html) module, it provides a _lot_ of functionality.
-
-Filesystem access is part of a broader type of operations called **IO**, which stands for Input/Output. IO also includes accessing databases and communicating on a network. We're spending most of our time using the HTTP protocol when communicating over networks, but IO includes all protocols and data formats, and databases. All IO operations should be performed asynchronously because they often take much longer than performing the in-memory tasks most of our application is written to do.
-
-Most of our web development work will not include operating on files. Most of it will involve databases and network communication. However, filesystem operations provide a great precursor into the asynchronous programming practices we'll apply with databases and networking, without having to understand the surrounding technology. The added benefit is understanding how to work with files, which is _very_ handy when programming local scripts.
-
-
-### Reading a text file
-
-To read a text file, we need the path to the file we want to read. In the example below, we're using the `path.join` function to create the path to the `students.json` file.
-
-```js
-// Include modules provided by Node.js
-var fs = require('fs')
-var path = require('path')
-
-function readAsync () {
- var studentsFile = path.join(__dirname, 'students.json')
- fs.readFile(studentsFile, 'utf-8', showContents)
-}
-
-function showContents (err, contents) {
- if (err) {
- return console.log(err.message)
- }
- console.log(contents)
-}
-```
-
-The contents of the file, `contents`, will be passed into our error-first callback function. We're console logging the contents if no error was provided.
-
-
-### Writing a text file
-
-To write a text file, we need the path we want to create and the contents we want for the file.
-
-```js
-// Include modules provided by Node.js
-var fs = require('fs')
-var path = require('path')
-
-function writeAsync () {
- var teacherFile = path.join(__dirname, 'teacher.json')
- var teacherJson = JSON.stringify({name: 'Don'})
- fs.writeFile(teacherFile, teacherJson, function (err) {
- if (!err) {
- verifyExists(teacherFile)
- }
- })
-}
-
-function verifyExists (teacherFile) {
- fs.exists(teacherFile, function(exists) {
- console.log(teacherFile, 'exists:', exists)
- })
-}
-```
-
-Instead of having to create a string buffer, the `writeFile` function will also accept just a normal string, which is returned from `JSON.stringify`. The anonymous function we're using as our error-first callback only accepts an error because there isn't anything else to return. If no error is provided we use `fs.exists` to determine if the file was created.
-
diff --git a/async/promises.md b/async/promises.md
index 2e5a02b..448025d 100644
--- a/async/promises.md
+++ b/async/promises.md
@@ -1,7 +1,6 @@
-Promises are a pattern/ style/ opinion about how to write synchronous functions.
-They are a direct response to Callback Hell.
+Promises are a pattern/style for writing synchronous functions. They are a direct response to Callback Hell.
-Here's an example of what a promisified superagent function looks like :
+Here's an example of what a promisified superagent function looks like:
```js
var Promise = require('promise');
@@ -16,7 +15,7 @@ request.get('http://google.com')
});
```
-from : https://www.npmjs.com/package/superagent-promise
+From: https://www.npmjs.com/package/superagent-promise
Here's a more 'nested' example of Promises, which also using `Promise.denodeify` to convert callback-style async functions into promise-style async functions:
diff --git a/async/testing.md b/async/testing.md
deleted file mode 100644
index 59039de..0000000
--- a/async/testing.md
+++ /dev/null
@@ -1,40 +0,0 @@
-Let's say we want to test and write an asynchronous function `readJson`, which given a path to a JSON file returns the object represented by the file.
-
-Our initial approach might look something like:
-
-```js
-test('reads a json file', function (t) {
- var path = __dirname + '/data.json'
- var object = readJson(path)
- t.ok(object)
- t.end()
-})
-```
-
-However if we read our file asynchronously with `fs.readFile`, it's impossible for `readJson` to return synchronously. This is because `fs.readFile` is async: the filesystem read takes time and subsequent lines of code will be run before the contents of the file are ready to be used.
-
-In synchronous code
-
-* to send data to the caller we use `return data`.
-* to send an error to the caller we use `throw err`.
-
-In asynchronous code
-
-* to send data to the caller we use `callback(null, data)`.
-* to send an error to the caller we use `callback(err)`.
-
-This means `readJson` must also take a callback!
-
-Let's try again:
-
-```js
-test('reads a json file', function (t) {
- var path = __dirname + '/data.json'
- readJson(path, function (err, object) {
- t.error(err)
- t.ok(object)
- t.end()
- })
-})
-```
-
diff --git a/async/versus-sync.md b/async/versus-sync.md
deleted file mode 100644
index 3df4d34..0000000
--- a/async/versus-sync.md
+++ /dev/null
@@ -1,36 +0,0 @@
-Every function in JavaScript is either synchronous or asynchronous. It's important to understand the difference because synchronicity defines how the function behaves to the code that calls it. When your code calls a _synchronous_ function, the function makes your code wait until it's finished before letting the next line run (also called _blocking_). This is true for most of the functions you've called so far, and likely all of the functions you've written so far. An _asynchronous_ function returns control to your code right away while it continues to do its work. This allows your code and the function to be working at the same time, asynchronously. Here are some examples:
-
-```js
-console.log('before')
-synchConsoleLog('working') // synchronous function
-console.log('after')
-```
-
-As you would expect, the output to the console will look like:
-
-```
-before
-working
-after
-```
-
-Now let's consider an async example:
-
-```js
-console.log('before')
-asyncConsoleLog('working') // async function
-console.log('after')
-```
-
-Depending on how long `asyncConsoleLog` takes to execute, the output of this could be:
-
-```
-before
-after
-working
-```
-
-Async functions are appropriate when they are going to take a long time to complete, so the calling code isn't blocked. It turns out that it takes a relatively long time to read or write to the filesystem (the hard drive) and the network (e.g. sending an HTTP request). In these cases, it's common to use async functions.
-
-The calling code often needs to know when the async function has finished its work. It's also common for the async function to return something (a result, error code or status change) which the calling code needs. In JavaScript, there are a number of different ways to approach this issue: callbacks, promises, and generators. We'll get to promises (and maybe generators) later in the course, but callbacks are the easiest to understand and very common.
-
diff --git a/command-line/aliases.md b/command-line/aliases.md
index 61428fe..b43e9a3 100644
--- a/command-line/aliases.md
+++ b/command-line/aliases.md
@@ -1,18 +1,30 @@
+# Command Line Aliases
+
If you have a command you run often, you might like to make a short-cut name for it.
Examples of commands that might be useful to have short-hands for:
+
- `git checkout origin master`
- `cd ~/projects/EDA`
- `git log --graph --stat`
- `ps auxw | grep ...` (where ... is some process you're searching for)
-You can create aliases in your `~/.bashrc` (or `~/.zshrc` file if you're using zsh)
+This is how you create them:
-They look like this :
-
-```bash
-alias gcom="git checkout origin master"
-alias eda="cd ~/projects/EDA"
+```sh
+alias gcm="git checkout origin master"
+alias eda="cd ~/workspace"
alias glog="git log --graph --stat"
alias findps="ps auxw | grep"
-```
\ No newline at end of file
+```
+
+Now to run `git checkout origin master` you can simply type `gcm` by itself.
+
+To make sure your aliases are available after you reboot, you can create them in your `~/.zshrc` if you're using the Zsh shell or in your `~/.bashrc` file if you're using the Bash shell.
+
+To see which aliases have already been created, run the `alias` command by itself. If you're looking for a specific alias, you can `grep` it. For example, to look for an alias that has _checkout_ somewhere in it, try this:
+
+```sh
+alias | grep checkout
+```
+
diff --git a/command-line/shell-scripts.md b/command-line/shell-scripts.md
index 998fb8e..12d267c 100644
--- a/command-line/shell-scripts.md
+++ b/command-line/shell-scripts.md
@@ -1,6 +1,8 @@
-If you want to do anything more complex that a single command, like including some conditional logic, or loops, you a shell script is what you want.
+# Shell scripts
-Make a file called `findTrailingSpace`
+If you want to do anything more complex that a single command, like including some conditional logic, or loops, a shell script is what you want. And you can create them in JavaScript.
+
+Make a file called `findTrailingSpace`:
```js
#!/usr/bin/env node
@@ -34,26 +36,27 @@ fs.readFile( targetFile, 'utf8', function(err, data) {
```
-You can run this by running `node findTrailingSpace somefile` - in this mode this is a javascript script.
-Notice unix doesn't care you didn't put `.js` on the end of your filename... while file extensions are polite, if you don't add them, it just doesn't care.
+You can run this by running `node findTrailingSpace somefile`. In this mode, this is a JavaScript script. Notice that Unix doesn't care that you didn't put `.js` on the end of your filename. While file extensions are polite, if you don't add them, your shell doesn't care.
-To make this a full shell script we want to make it executable (as in can run it without calling node in front of it all the time)
+To make this a full shell script, we want to make it executable so we can run it without including `node` in front of it all the time.
-Do this by running:
+Make it executable by running:
-```
+```sh
chmod +x findTrailingSpace
```
-(where +x means 'add executeable'. Run `man chmod` to read more about what chmod is about)
+`+x` means 'add executeable'. Run `man chmod` to read more about what chmod is about.
-Now the terminal will read the first line, determine you want to run the contents with node, so we can run our script by just calling:
+Now the shell will read the first line (called a hashbang or shebang) to find out what to run the rest of the script with; `node` in our case. Now we can run our script by calling:
```
./findTrailingSpace somefile
```
-Extras for experts:
-- link the concept of an alias and a script so you can call the script from anywhere
-- read about unix _path_ and how to put your script in the path
-- check out this link for some more interesting shell scripts [Cool shell scripts](http://intuitive.com/wicked/wicked-cool-shell-script-library.shtml), try and implement them yourself!
\ No newline at end of file
+More to consider:
+
+- Link the concept of an alias and a script so you can call the script from anywhere.
+- Read about the Unix _path_ and how to put your script in the path.
+- Check out this link for more interesting shell scripts: [Cool shell scripts](http://intuitive.com/wicked/wicked-cool-shell-script-library.shtml). Have a go at implementing them yourself.
+
diff --git a/culture/challenges.md b/culture/challenges.md
deleted file mode 100644
index 037f473..0000000
--- a/culture/challenges.md
+++ /dev/null
@@ -1,9 +0,0 @@
-The challenges at Dev Academy are made for learning. Completing things is very satisfying, but in this course you will not have time to finish everything. Side note: the same is true in life.
-
-```
-Completion !== Learning
-```
-
-It's important to pay attention to your learning and work on how you most effectively and efficiently learn. You will need to prioritise what you spend you time on. Specifically, we'll be supporting you to ask:
-
-> Is this advancing my learning?
diff --git a/culture/opensource.md b/culture/opensource.md
index a35d6dd..e062509 100644
--- a/culture/opensource.md
+++ b/culture/opensource.md
@@ -1,41 +1,43 @@
+# Open Source
+
It's time to give back to the community! Here we present some thoughts designed to guide your first contributions to open source software.
-### Be respectful
+## Be respectful
This should underpin everything you do when working with projects and their maintainers. Remember ***IKE***. These people give much of their time and patience to help their community: don't make their life harder! Say, "thank you".
-### Read contribution guidelines and documentation
+## Read contribution guidelines and documentation
We can't stress this enough. If you see guidelines, follow them _even if they're different to what you normally do_. If the maintainers want semicolons, use semicolons! If they want nine spaces in every indent, that's up to them. Your job isn't to change their minds and make them see the One True Way to format code.
-### Be precise
+## Be precise
Your contribution will be examined by others. Make sure you've spell-checked and formatted documentation. Check for broken links. Test code.
-### Compare with other contributions
+## Compare with other contributions
If you're not sure how to format your pull request or issue, look at what others have done. Try to gauge what the minimum standard for contribution is, and exceed it.
-### Make sure the tests still pass
+## Make sure the tests still pass
If a project has unit tests, _run_ them before submitting your PR. Make sure you didn't break something!
-### It's not about you
+## It's not about you
Sometimes you might get an answer to a question or a pull request that strikes you as abrupt or even rude: chances are, it's not about you. Some projects receive hundreds, even thousands of issues and PRs. The maintainers might just be trying to get through the day as quickly as possible, and sometimes that bleeds out into frustration. Remember, text is low-fidelity communication: maybe some context was lost between the two parties?
-### Except maybe when it is about you
+## Except maybe when it is about you
Everybody brings something different to a project. Don't be afraid to suggest something new, _especially_ if you can back it up with a contribution (i.e. if you fix the problem you're pointing out).
-### Resources
+## Resources
- [Trending in open source](https://github.com/trending) - GitHub's list of trending projects
- [14 Ways to Contribute to Open Source without Being a Programming Genius or a Rock Star](http://blog.smartbear.com/programming/14-ways-to-contribute-to-open-source-without-being-a-programming-genius-or-a-rock-star/)
@@ -43,3 +45,4 @@ Everybody brings something different to a project. Don't be afraid to suggest so
- [The Beginner’s Guide to Contributing to Open Source Projects](https://blog.newrelic.com/2014/05/05/open-source_gettingstarted/)
- [CodeMontage](https://www.codemontage.com/) - community-driven projects for NPOs
- [CodeTriage](https://www.codetriage.com/)
+
diff --git a/culture/pairing-intro.md b/culture/pairing-intro.md
deleted file mode 100644
index 97b0bce..0000000
--- a/culture/pairing-intro.md
+++ /dev/null
@@ -1,52 +0,0 @@
-Pair programming is an agile software development technique in which two programmers work as a pair together on one workstation. One, the driver, writes code while the other, the navigator, focuses on the bigger picture, and immediately spots mistakes.
-
-Together, the programmers help each other hold strong attention on the task.
-
-It is a simple but very effective tool.
-
-Watch Fiona and Semira's explanation for an explanation of how to pair program.
-
-Then watch Codr.tv's episode on Pair Programming to hear about how Pairing is used as a tool in the industry.
-
-
-## Environment
-
-The options we've found for pairing, in order of effectiveness, are:
-
-1. Pair in person
-2. Video call while working collaboratively on a remote computer such as Cloud9.
-3. Video call with screen sharing (Skype, Google Hangouts, appear.in, etc.)
- **If you can't meet up in person, and you don't have adequate internet connection for options 2 or 3, you won't have adequate communication lines to pair program**
-
-Instead, you can get some of the benefits with:
-
-1. Phone call and slack to discuss approaches, ideas and issues.
-2. Share pseudocode and code on slack.
-
-
-## Prerequisites
-
-* Something to work on together
-
-
-## When pairing:
-
- - First, check-in with your pair
- - Assign roles (driver vs navigator)
- - Explain your thinking in a clear concise manner
- - Keep a timer, to monitor how long you have been in a certain role
-
-
-## Capabilities
-
-You are comfortable:
-
- - taking time to check in with another person before coding together
- - understanding how to use pair programming effectively
-
-
-## Resources
-
- - [Pair Programming - Fiona and Semira @ Generation Code (Video)](https://www.youtube.com/watch?v=vgkahOzFH2Q). Their video may seem silly, but the points they touch are very important, and we see the pitfalls they highlight happening on the course all the time.
- - [Codr.tv - Pair Programming (Video)](https://www.youtube.com/watch?v=5ySLQ5_cQ34)
-
diff --git a/culture/researching-tools.md b/culture/researching-tools.md
deleted file mode 100644
index 2afdc93..0000000
--- a/culture/researching-tools.md
+++ /dev/null
@@ -1,4 +0,0 @@
-Being curious about the differences between various setups and tools is a healthy pattern to cultivate.
-It's easy to avoid tools because they sound complex.
-Use the skills you've learned about time-boxing to learn about a new tool if you're not familiar with it.
-Try it out, maybe copy some code or do a bit of a tutorial, but make sure you get to writing real code as fast as possible.
diff --git a/culture/style-guides.md b/culture/style-guides.md
deleted file mode 100644
index ff66af0..0000000
--- a/culture/style-guides.md
+++ /dev/null
@@ -1,14 +0,0 @@
-Software projects commonly require developers to write code that conforms to a specific style. A style guide specifies how the code should be formatted, often in excrutiating detail. Writing code that conforms to a style guide has the following advantages and is strongly recommended:
- * Code written by someone else that conforms to a familiar style will be more readable than code that does not.
- * Your brain has powerful pattern matching capabilities - if the code is well-formatted and in a familiar style you will be able to spot errors **much faster** than if it wasn't well-formatted.
- * Style guides have rules that catch common bugs.
- * Developers use tools to automate the process of formatting and checking code to see if it conforms to a style (linting).
-
-Three JavaScript style guides in common usage are:
- * [AirBnB Style Guide](https://github.com/airbnb/javascript)
- * [Google Style Guide](https://google.github.io/styleguide/javascriptguide.xml)
- * [Standard](https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style)
-
-## Resources
-
- * [Douglas Crokford: Programming Style & Your Brain](https://www.youtube.com/watch?v=_EANG8ZZbRs)
diff --git a/databases/foreign-keys.md b/databases/foreign-keys.md
deleted file mode 100644
index 6747838..0000000
--- a/databases/foreign-keys.md
+++ /dev/null
@@ -1,2 +0,0 @@
-A foreign key is a field in a table which references the primary key of another table so we might have Person [id, name] and Pet [id, name, person_id].
-In this case the field person_id on Pet is a foreign key which references the primary key on Person (id).
\ No newline at end of file
diff --git a/databases/intro.md b/databases/intro.md
deleted file mode 100644
index d58fbc6..0000000
--- a/databases/intro.md
+++ /dev/null
@@ -1,79 +0,0 @@
-Databases make it easy for applications to save and retrieve data. They allow the data to be accessed by multiple users and potentially many applications while maintaining performance.
-
-There are different kinds of databases. They vary based on how they store data, which can be advantageous to different types of apps depending on the data it operates on and how it needs to be structured. Examples of these database types include: relational, document, object, and graph. We'll focus on relational databases because they are very common and are appropriate for many types of applications.
-
-
-### Files versus servers
-
-Databases may run on the same computer as the web server or on a different one. Regardless, it is an explicitly different service. In the same way a web server is an application waiting for HTTP requests, a database server is an application waiting for data-related requests. Database services require credentials in order to connect to them. So before you can store or retrieve any data to a database, you must first create a connection using predefined credentials. Examples of database servers, also called Database Management Systems (DBMS) include: Oracle, MySQL, PostgreSQL and MS SQL Server. These are all relational DBMS, or RDBMS.
-
-There are also some file-based relational databases, such as Microsoft Access and SQLite. These are appropriate when our application is only used by one user at a time because there isn't a service managing the data. However our application will access the data the same way it would if we were using an RDBMS. There are significant disadvantages to using file-based databases and they should normally not be used with production web applications. However, they are useful during development and for single-user applications, such as mobile apps.
-
-
-### Structured storage (relational)
-
-Relational data is stored in a structured way so it can be saved and retrieved easily. Fortunately you are already familiar with a structure very similar to databases: spreadsheets. While databases and spreadsheets are very different, there are enough similarities in how they conceptualise data that's it's useful to compare them.
-
-**Entities**, also called tables, are similar to a single sheet of a spreadsheet. Each database will have at least one of these, but often has many. An example of an entity is: `Users`.
-
-**Fields**, also called columns, are similar to the the vertical lines in the sheet of a spreadsheet. Each entity will have at least one field. Examples of fields are: `first_name`, `last_name` and `username`. There are some special fields we'll cover later.
-
-**Records**, also called rows, are similar to the horizontal lines in the sheet of a spreadsheet. An entity will only have records when there is data stored. Until then, there are no records. An examples of a record is: 'Bernie', 'Sanders', 'burningsand'.
-
-
-### Schema versus records
-
-A database is made up two kinds of information: data and metadata. Data is the actual data being stored - 'Bernie', 'Sanders' and 'burningsand' in the example above. Metadata is the information about the data. Entities and fields define the kind of data being stored: first name, last name, and usernames of Users. It's important that you keep these concepts separate when you think about databases.
-
-
-### Data operations
-
-After making a connection, you will perform your operations. Most databases permit 4 different types of operations and a very common mneumonic to refer to them is CRUD: create, read, update, and delete. Each of these operations represent something done on a piece of data, also called a record.
-
-* **Create**: a new record is saved.
-* **Read**: an existing record is retrieved.
-* **Update**: an existing record is changed (edited).
-* **Delete**: an existing record is removed.
-
-
-### Structured Query Language (SQL)
-
-SQL is the language we use to perform CRUD operations on relational databases. Here are some examples of SQL statements that perform CRUD operations:
-
-**Create**
-
-```sql
-INSERT INTO Users (id, firstName, lastName, username)
-VALUES (123, 'Brendan', 'Eich', 'beich');
-```
-
-**Read**
-
-```sql
-SELECT firstName, lastName FROM Users;
-```
-
-**Update**
-
-```sql
-UPDATE Users
-SET firstName='Haskell', lastName='Curry', username='hascurry'
-WHERE id=10;
-```
-
-**Delete**
-
-```sql
-DELETE FROM Users WHERE id = 123;
-```
-
-
-## Database maintenance
-
-There are a number of tools you can use to manage your databases. Some are graphical and some are libraries you can automate with code. The graphical tools are specific to the database engine you're using, but the libraries can often work with a number of different similar databases (e.g. RDBMS).
-
-**Migrations** provide an automated way to create, modify and undo changes to the database schema.
-**Seeding** provides an automated way to populate the database with data. These are useful when setting up a new development environment and doing deployments.
-
-We'll be using [Knex.js](https://knexjs.org) as a library to perform database operations and database maintenance tasks. Review the [Knex.js documentation on migrations](https://knexjs.org/#Migrations) and [schema building](https://knexjs.org/#Schema-Building) to create migrations that will establish the database schema.
-
diff --git a/databases/joins.md b/databases/joins.md
index 06e1d55..ecd243a 100644
--- a/databases/joins.md
+++ b/databases/joins.md
@@ -1,3 +1,4 @@
+# Joins
Imagine I wanted to find the names of all the pets who belonged to Jane. This could be done with two queries
diff --git a/databases/knex-joins.md b/databases/knex-joins.md
deleted file mode 100644
index f4abc31..0000000
--- a/databases/knex-joins.md
+++ /dev/null
@@ -1,121 +0,0 @@
-### Combining tables for fun and profit
-
-Sometimes we need information from more than one table. If we keep our users in one table, and our user demographic data in another, we need some way to associate (say) a user's name with their age:
-
-***users***
-
-| id | name |
-|:---|:---------------|
-| 8 | Orinocco |
-| 12 | Tomsk |
-| 3 | Uncle Bulgaria |
-
-***user_demographics***
-
-| id | user_id | age |
-|:---|:--------|:----|
-| 1 | 8 | 3 |
-| 2 | 12 | 4 |
-| 3 | 3 | 61 |
-
-A **join** allows us to combine the information based on the values in a column that exists in both tables, in this case combining values when `id` is equal to `user_id`:
-
-| name | age |
-|:---------------|:----|
-| Orinocco | 3 |
-| Tomsk | 4 |
-| Uncle Bulgaria | 61 |
-
-
-### A nod to normalisation
-
-The question you're probably asking is, "Why not put all the information in one table to begin with?" Well, several reasons, centering around a concept called _normalisation_. This is a huge topic in itself, but can be summarised at a beginning level by saying, "Keep information in lots of small tables and link them to each other using unique IDs." This has a number of benefits including reducing redundancy, ease of adding new types of data, and reducing complexity.
-
-
-### Knex joins
-
-Using Knex.js we can perform joins without having to know the SQL syntax for the query:
-
-```js
-knex('dogs')
- .join('breeds', 'dogs.breed_id', '=', 'breeds.id')
- .select('dogs.name', 'breeds.name as breed')
-```
-
-In raw SQL this translates to:
-
-```sql
-SELECT dogs.name, breeds.name AS breed
-FROM dogs
-INNER JOIN breeds ON dogs.breed_id = breeds.id
-```
-
-***dogs***
-
-| id | name | breed_id |
-|:---|:-------|:---------|
-| 1 | Daisy | 5 |
-| 2 | Dexter | 3 |
-| 3 | Clarry | 2 |
-
-***breeds***
-
-| id | name |
-|:---|:----------------------|
-| 1 | Boxer |
-| 2 | Spoodle |
-| 3 | King Charles Cavalier |
-| 4 | Bulldog |
-| 5 | Mutt |
-
-| name | breed |
-|:----------|:----------------------|
-| Daisy | Mutt |
-| Dexter | King Charles Cavalier |
-| Clarry | Spoodle |
-
-Note a few things about the above result:
-
- 1. Not _all_ of the dog breeds are listed: only those that correspond to the dogs in the first table
- 2. Only the columns we asked for are returned, and they are labelled `name` and `breed`.
-
-
-### Name conflicts
-
-Let's talk about that second point for a moment. Why do we use this syntax?
-```js
- .select('dogs.name', 'breeds.name as breed')
-```
-The trick is, Knex returns column names as object properties. What's wrong with this picture?
-```js
- [
- {
- name: 'Daisy',
- name: 'Mutt'
- }
- ]
-```
-Of course, we can't have an object with two properties the same, so what actually happens is the second one gets overwritten:
-```js
- [
- {
- name: 'Mutt'
- }
- ]
-```
-Obviously that's not what we want! The solution is to provide another name, an _alias_, for any properties that conflict in this way. We can write `'tablename.columnname as foobar'` to achieve this. In the example above, our output from Knex looks like so:
-```js
- [
- {
- name: 'Daisy',
- breed: 'Mutt'
- },
- {
- name: 'Dexter',
- breed: 'King Charles Cavalier'
- }
- ]
-```
-So if we were to describe the above query in English we could say:
-
-"Join the dogs table and the breeds table where the breed id matches. Then return the data in two columns: "name" (the name column in the dogs table) and "breed" (the name column in the breeds table)."
diff --git a/databases/knex-keys.md b/databases/knex-keys.md
deleted file mode 100644
index 35e4edd..0000000
--- a/databases/knex-keys.md
+++ /dev/null
@@ -1,115 +0,0 @@
-### A key, you say?
-
-Keys are integral to Relational Database Management Systems (RDBMS). Each _record_ or _row_ can contain one or more keys, and there are several different types.
-
-Records can be identified either by a single key or a combination of keys. Often, but not always, they'll be numbers. There are two types we'll concern ourselves with for now: **primary** and **foreign** keys.
-
-
-### Primary keys
-
-Typically your `id` column will be a primary key. They have a _unique constraint_, which means that each value must be unique. You can't have two 1's, three 2's, etc. Imagine the chaos if the users in your database could share user IDs!
-
-Here's a Knex.js migration that creates a simple table with a primary key:
-
-```js
-exports.up = function (knex, Promise) {
- return Promise.all([
- knex.schema.createTable('users', function (table) {
- table.increments('id').primary()
- table.string('name')
- })
- ])
-}
-
-exports.down = function (knex, Promise) {
- return Promise.all([
- knex.schema.dropTable('users')
- ])
-}
-```
-
-***users***
-
-| id (PK) | name |
-|:--------|:-----------|
-| 1 | basie |
-| 2 | fitzgerald |
-| 3 | coltrane |
-| 4 | thelonious |
-
-Primary keys can't be null or 0. Every record in a table with a primary key has to have a key assigned. The `.increments()` function above just makes sure that when you add a new row, an `id` will be assigned with the value of the highest existing `id` + 1.
-
-
-### Foreign keys
-
-Often we'll need to relate a record in one table to a record in another. Foreign keys link records from different tables together. Using _constraints_, they can help maintain the integrity of the data and enable joins to combine tables.
-
-Here's how Knex defines foreign keys:
-
-```js
-exports.up = function (knex, Promise) {
- return Promise.all([
- knex.schema.createTable('dogs', function (table) {
- table.increments('id').primary()
- table.string('name')
- table.integer('breed_id').references('breeds.id')
- }),
- knex.schema.createTable('breeds', function (table) {
- table.increments('id').primary()
- table.string('name')
- })
- ])
-}
-
-exports.down = function (knex, Promise) {
- return Promise.all([
- knex.schema.dropTable('dogs'),
- knex.schema.dropTable('breeds')
- ])
-}
-```
-
-Notice the `.references('breeds.id')`? That tells the database that we want `dogs.breed_id` to refer to `breeds.id`: we're linking the two tables together using `breed_id` as the key.
-
-***dogs***
-
-| id (PK) | name | breed_id (FK) |
-|:--------|:-------|:--------------|
-| 1 | Daisy | 3 |
-| 2 | Clarry | 2 |
-
-***breeds***
-
-| id (PK) | name |
-|:--------|:--------|
-| 1 | Boxer |
-| 2 | Spoodle |
-| 3 | Mutt |
-
-Put another way, `breed_id` is a foreign key that references `id` on the `breeds` table.
-
-
-### Constraints
-
-We've touched on the _unique constraint_ that applies to primary keys (no two can be the same value). Foreign keys can have constraints too, that define what should happen when an attempt is made to remove or alter the record that the key is pointing to.
-
-Take the above table for example. Say someone tries to delete the 'Mutt' row in the `breeds` table, with `id` 3. We already have a record that refers to that row: 'Daisy' in `dogs` would be left without a breed! This seems like a bad thing, and it is. We don't want IDs that point off into nowhere, referring to no record. If someone later managed to add a completely different breed having an `id` of 3, Daisy's breed would be changed without anyone asking her permission.
-
-The solution is to add a constraint defining what should happen if a breed is deleted. We call this constraint _ON DELETE_. There are several possible values for the constraint. Two of the most important are _RESTRICT_ and _CASCADE_.
-
-RESTRICT means that the attempt to remove the 'Mutt' record will _fail_ if any of the records in the `dogs` table are mutts. Each dog would have to have their breed changed before the attempt to delete 'Mutt' could succeed.
-
-CASCADE means that all dogs that are mutts will be deleted when the 'Mutt' record is deleted! For obvious reasons, be careful with this one.
-
-We can also apply similar values to an _ON UPDATE_ constraint, which as you might have guessed defines what the database should do when a record in `breeds` is changed, but not deleted.
-
-Here's how Knex handles these constraints:
-
-```js
- table.integer('breed_id')
- .references('breeds.id')
- .onDelete('RESTRICT')
- .onUpdate('CASCADE')
-```
-
-In other words, when someone tries to remove a breed that is referenced in `dogs`, don't allow it; when someone merely updates a breed, the change spreads to all dogs of that breed. For example, if 'Mutt's `id` was changed from 3 to 4, Daisy's `breed_id` would change to 4 as well.
diff --git a/databases/knex-routes.md b/databases/knex-routes.md
deleted file mode 100644
index 7e9e4fd..0000000
--- a/databases/knex-routes.md
+++ /dev/null
@@ -1,88 +0,0 @@
-When we start out with Express, we often create routes that show static (unchanging) data, or we've used them to load and save from the filesystem. We can use a very similar layout to load and save data from a database using Knex.js.
-
-
-### Promises
-
-The main difference of course is that Knex functions return promises. We won't actually have any data to work with unless we wait for the promises to _resolve_ or _reject_. For example, this sort of thing won't work:
-
-```js
-app.get('/users', function (req, res) {
- var users = knex('users').select()
- res.send(users)
-}
-```
-
-Instead, we'll need to make use of the `.then()` and `.catch()` functions to ensure that the data is available for us to use (and grab any errors that might occur):
-
-```js
-app.get('/users', function (req, res) {
- knex('users')
- .select()
- .then(function (data) {
- res.send(data)
- })
- .catch(function (err) {
- console.error(err.message)
- res.status(500).send("Couldn't show you the users!")
- })
-}
-```
-
-### Extracting the database details to one place
-
-Following the [Single Responsibily Principle](https://en.wikipedia.org/wiki/Single_responsibility_principle), it's much cleaner to have the routes focus on the request and response and extract the details of database access into a separate module. Here's how you could extract them:
-
-```js
-// queries.js
-
-var development = require('./knexfile').development
-var knex = require('knex')(development)
-
-function getUsers () {
- return knex('users').select()
-}
-
-// An example user object: {name: 'feroze', email: 'feroze@gmail.com'}
-function insertUser (user) {
- return knex('users').insert(user)
-}
-
-module.exports = {
- getUsers: getUsers,
- insertUser: insertUser
-}
-```
-
-```js
-// app.js
-// ...
-
-var queries = require('./queries')
-
-app.get('/users', function (req, res) {
- queries.getUsers()
- .then(function (users) {
- res.send(users)
- })
- .catch(function (err) {
- console.error(err.message)
- res.status(500).send("Can't display users!")
- })
-})
-
-app.post('/users', function (req, res) {
- var newUser = {
- name: req.body.name, // name stored in a submitted form body
- email: req.body.email
- }
-
- queries.insertUser(newUser)
- .then(function () {
- res.sendStatus(200)
- })
- .catch(function (err) {
- console.error(err.message)
- res.status(500).send("Couldn't insert a new user.")
- })
-})
-```
diff --git a/databases/relationships.md b/databases/relationships.md
deleted file mode 100644
index f572afa..0000000
--- a/databases/relationships.md
+++ /dev/null
@@ -1,98 +0,0 @@
-Different types of databases represent their records in different ways. For example, document databases use _composition_, wherein records are represented _inside_ of other entities. An example of this would be the relationship between a `User` and their `Bookmarks`. Composition would place the bookmark data inside the user record perhaps as a property on the users object.
-
-Relational databases represent their records in separate _tables_ and relationships are established between tables. In our bookmarks example, there would be two tables: users and bookmarks. Each bookmark record would include a `user_id` field that refers to the `id` field of an associated record in the users table.
-
-```
-+--------------------+ +-------------+
-| Users | | Bookmarks |
-+--------------------+ +-------------+
-| id |<--- | id |
-| name | \ | link |
-| address | ---| user_id |
-+--------------------+ +-------------+
-```
-
-Modern databases are highly optimised to perform fast queries across multiple tables at once - these are called joins.
-
-
-### Types of relationship
-
-The relationship between tables is often described using broad _types_ that reflect a relationship modelled on 'real life'. These are usually described as _one-to-one_, _one-to-many_, and _many-to-many_.
-
-One of the canonical examples is the relationship authors have with books: for example, one book may have many authors, and one author may have written many books. We often say an author _HAS MANY_ books, and a book _HAS MANY_ authors. (Even if it doesn't, it _could_!)
-
-
-### One to one
-
-A user _HAS ONE_ profile.
-
-***users***
-
-| id | username |
-|----|------------|
-| 1 | xkcd |
-| 2 | smbc |
-| 3 | rms |
-| 4 | greenblatt |
-| 5 | gosper |
-
-***profiles***
-
-| id | website | profile_image | user_id |
-|----|----------------------|---------------|----------|
-| 1 | https://xkcd.com | randall.jpg | 1 |
-| 2 | https://stallman.org | rms.jpg | 3 |
-
-Each `user_id` will occur only once within the `profiles` table.
-
-
-### One to many
-
-A user _HAS MANY_ blog posts. Even if they've only written one so far, they _could_ have thousands! So we think of the relationship as _one-to-many_.
-
-***users***
-
-| id | username |
-|----|------------|
-| 1 | xkcd |
-| 2 | smbc |
-| 3 | rms |
-| 4 | greenblatt |
-| 5 | gosper |
-
-***posts***
-
-| id | title | user_id |
-|----|-------------------|---------|
-| 1 | Thing Explainer | 1 |
-| 2 | The GNU Manifesto | 3 |
-| 3 | GNU Emacs Manual | 3 |
-
-Notice that `user_id` is not unique in the `posts` table: it can appear as many times as each user has posts.
-
-
-### Many to many
-
-In our hypothetical system, much like Facebook, users can have 'friends'. There is practically no limit on the number of friends a user can have. A user _HAS MANY_ friends, and each friend might have many friends.
-
-***users***
-
-| id | username |
-|----|------------|
-| 1 | xkcd |
-| 2 | smbc |
-| 3 | rms |
-| 4 | greenblatt |
-| 5 | gosper |
-
-***friends***
-
-| id | user_id | friend_id |
-|----|---------|-----------|
-| 1 | 4 | 5 |
-| 2 | 3 | 4 |
-| 3 | 4 | 3 |
-| 4 | 5 | 4 |
-| 5 | 1 | 2 |
-
-Here again, the same `user_id` can appear more than once, but it can also appear as a `friend_id`. We don't need the user's username to make the friend connection.
diff --git a/databases/sql-intro.md b/databases/sql-intro.md
index 3648df8..cdf7874 100644
--- a/databases/sql-intro.md
+++ b/databases/sql-intro.md
@@ -17,4 +17,5 @@ WHERE id=123;
```
Delete
-`DELETE FROM Users WHERE id=123`
\ No newline at end of file
+`DELETE FROM Users WHERE id=123`
+
diff --git a/dom/dom-manipulation.md b/dom/dom-manipulation.md
deleted file mode 100644
index df4a5f1..0000000
--- a/dom/dom-manipulation.md
+++ /dev/null
@@ -1,6 +0,0 @@
-There are lots of tools for DOM manipulation at your disposal.
-For example:
-
- - Direct (vanilla) JavaScript: `document.body.appendChild(el)`
- - JQuery: `$(body).add(el)`
- - Many specialised JQuery alternatives
diff --git a/environment/deployment.md b/environment/deployment.md
deleted file mode 100644
index 2b3417d..0000000
--- a/environment/deployment.md
+++ /dev/null
@@ -1,19 +0,0 @@
-Deploying a web application is most certainly specific to the environment being deployed to. With that said, it is increasingly common for cloud providers to allow applications to be deployed using Git.
-
-Some cloud providers, such as Azure, are able to watch our GitHub repo, notice when we push a new commit to a specific branch we define, and clone it for deployment each time we push. Other cloud providers, such as Heroku, allow us to push directly to it. To do so, we just create a `git remote` that points to our account on the cloud platform. These approaches make deployment _really_ easy.
-
-
-### Deploying to Heroku
-
-These steps assume the file that starts your server is `server.js`. If it isn't, adjust the steps accordingly. The basic steps to deploy to Heroku are:
-
-* Create an account on heroku.com.
-* Install the Heroku Toolbelt.
-* Login to Heroku in your terminal with `heroku login`.
-* In the folder of your Node app, create the Heroku app with `heroku create YOUR_APP_NAME`.
-* Ensure your `package.json` has a `start` script of `node server.js`.
-* Ensure you have a `Procfile` whose only line is `web: node server.js`.
-* Push your app to Heroku with `git push heroku master`.
-* If you experience an error, use `heroku logs`.
-
-For more information on deploying a Node.js application to Heroku, see the [associated documentation](https://devcenter.heroku.com/articles/getting-started-with-nodejs#introduction).
diff --git a/environment/intro.md b/environment/intro.md
index c43e99c..e76ae44 100644
--- a/environment/intro.md
+++ b/environment/intro.md
@@ -1,4 +1,7 @@
+# Environments
+
It's common to have several different 'environments' that an application is run in.
+
They are :
- dev environment: for building locally and observing
- test environment: just for running tests, may have fake test data or a fake database
@@ -23,3 +26,4 @@ The package [dotenv](https://www.npmjs.com/package/dotenv) helps us set up envir
**VERY IMPORTANT** : make sure you have added `.env` to your `.gitignore` file, otherwise you might accidentally post your API keys on GitHub.
Worst case someone will use your keys to move money, post tweets, or max out your credit card. There are bots that trawl GitHub looking for API keys that have been commited by mistake, do not do it!
+
diff --git a/functional/closure.md b/functional/closure.md
index e70828d..af3e24c 100644
--- a/functional/closure.md
+++ b/functional/closure.md
@@ -1,82 +1,76 @@
+# Closures
+
A closure is a special kind of object that combines two things: a function, and the environment in which that function was created.
-Here's a powerful pattern that is an example of a closure: imagine instead of making a function that just doubles, we could write a function that makes a function that doubles .. or triples, or timeses by anything we want.
+Here's a powerful pattern that is an example of a closure: imagine instead of making a function that just doubles, we could write a function that makes a function that doubles or triples, or multiplies by anything we want.
```js
-function makeFunctionThatTimesesByN( n ) {
+function makeFunctionThatMultipliesByN (n) {
var newFunction = function(x) {
- return n*x
+ return n * x
}
return newFunction
}
-var double = makeFunctionThatTimesesByN(2)
-// imagine what the inside of makeFunctionThatTimesesByN looks like:
- // var newFunction = function(x) {
- // return 2*x // n = 2
- // }
- // return newFunction
-
-double(15)
-// => 30
+var double = makeFunctionThatMultipliesByN(2)
-var hexiply = makeFunctionThatTimesesByN(6)
-hexiply(7)
-// => 42
+// Imagine what the inside of makeFunctionThatMultipliesByN looks like:
+// var newFunction = function(n) {
+// return 2 * n // n = 2
+// }
+// return newFunction
+double(15) // returns 30
+var hexiply = makeFunctionThatTimesesByN(6)
+hexiply(7) // returns 42
```
-This is a wicked poweful trick for baking variables into functions, then passing that function around.
-For example, we can bake custom callback functions with specific details baked into their recipe, then hand that callback into an async function.
+This is a wicked powerful trick for baking variables into functions, then passing that function around. For example, we can bake custom callback functions with specific details baked into their recipe, then hand that callback into an async function.
+
-#### Example
+## Example
-In terms of a pizza delivery analogy, the closure would be the "make a home delivery callback function" and the ingredient we would back in would be "persons address" :
+In terms of a pizza delivery analogy, the closure would be the "make a home delivery callback function" and the ingredient we would back in would be "persons address".
-Robin places an order for a **Margherita**, and gives their address - **234 Aro Street**. Making pizza's is async, so We want to do something like this:
+Robin places an order for a **Margherita**, and gives their address - **234 Aro Street**. Making pizza's is async, so We want to do something like this:
```js
fs.createPizza( 'margherita', deliverPizza )
```
-But if deliverPizza is a callback ... that only takes `(err, pizza)` as arguments (where pizza is the result of a successful createPizza).
-How do we get the address into the callback?!!
+But if `deliverPizza` is a callback, that only takes `(err, pizza)` as arguments (where pizza is the result of a successful `createPizza`). How do we get the address into the callback?!!
-WE BAKE IT IN WITH A CLOSURE
+We bake it in with a closure.
```js
-function makeCustomDeliveryCallback( address ) {
- var customDeliveryCallback = function( err, pizza ) {
- if (err) // do something!
+function makeCustomDeliveryCallback (address) {
+ var customDeliveryCallback = function (err, pizza) {
+ if (err) // handle error
- deliver( pizza, address )
+ deliver(pizza, address)
}
return customDeliveryCallback
}
-
```
And use it like this:
```js
-var deliverToRobin = makeCustomDeliveryCallback( '234 Aro Street' )
-fs.createPizza( 'margherita', deliverToRobin )
+var deliverToRobin = makeCustomDeliveryCallback('234 Aro Street')
+fs.createPizza('margherita', deliverToRobin)
```
-
-Final note: typically closures are written more briefly :
-
+Final note: typically closures are written more briefly:
```js
-function makeCustomDeliveryCallback( address ) {
- return function( err, pizza ) {
- if (err) // do something!
-
- deliver( pizza, address )
+function makeCustomDeliveryCallback (address) {
+ return function (err, pizza) {
+ if (err) // handle error
+ deliver(pizza, address)
}
}
-
```
-Check out this great article for more detail: https://developer.mozilla.org/en/docs/Web/JavaScript/Closures
\ No newline at end of file
+Check out this great article for more detail: https://developer.mozilla.org/en/docs/Web/JavaScript/Closures
+
diff --git a/functional/immutable.md b/functional/immutable.md
index 409b94d..19d16ba 100644
--- a/functional/immutable.md
+++ b/functional/immutable.md
@@ -1,14 +1,22 @@
+# Immutability
+
Immutability is a pattern which asserts you're not permitted to mutate (change) an object once it's made.
-To make a change you need to make a 'new' object, which is a clone with the changes you want / need.
-This seems inconvenient, but affords some massive gains in certain contexts (e.g. when you're trying to determining whether anything has changed in a large data structure)
+To _change_ and object after it has been created, you must make a 'new' object, which is a clone of the original that includes the changes.
+
+This seems inconvenient, but affords some massive gains in certain contexts, such as when you're trying to determining whether anything has changed in a large data structure.
+
+`Immutable` is a popular library to help you achieve this behaviour.
+
+https://facebook.github.io/immutable-js | https://www.npmjs.com/package/immutable
+
+It provides objects which have methods you will be familiar with, but are immutable:
-https://facebook.github.io/immutable-js/ | https://www.npmjs.com/package/immutable
+| Node | Immutable.js |
+| -------- | ---------------- |
+| `Array` | `Immutable.List` |
+| `Set` | `Immutable.Set` |
+| `Object` | `Immutable.Map`* |
-Immutable.js provides objects which have methods you will be familiar with, but are immutable:
+* _Technically, there's a [Map in ES6](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map) which you could read about._
-Node | Immutable.js | notes
--------|--------------|-----
-`Array` | `Immutable.List` |
-`Set` | `Immutable.Set` |
-`Object` | `Immutable.Map` | _technically, there's a [Map in ES6](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map) which you could read about_
\ No newline at end of file
diff --git a/functional/pure-functions.md b/functional/pure-functions.md
new file mode 100644
index 0000000..7d956b0
--- /dev/null
+++ b/functional/pure-functions.md
@@ -0,0 +1,29 @@
+# Pure Functions
+
+A pure function is a function which follow a specific set of rules:
+
+* Will not mutate _any_ of its arguments
+* Will not cause _any_ side effects outside of itself
+* Will _always_ return the same value given the same arguments
+
+Here is a simple example:
+
+```js
+const square = x => x * x // ES6
+
+function square (x) { // ES5
+ return x * x
+}
+```
+
+Impure functions are less predictable. By definition, they mutate something; either something passed to it, or a variable outside of its scope.
+
+```js
+var someThing = []
+
+function (x) {
+ someThing.push(x) // this will mutate someThing outside of the function's scope
+ return x++ // this will mutate the variable that was passed in
+}
+```
+
diff --git a/functional/pute-functions.md b/functional/pute-functions.md
deleted file mode 100644
index eabc15b..0000000
--- a/functional/pute-functions.md
+++ /dev/null
@@ -1,23 +0,0 @@
-A pure function is a function which takes arguements but which does not mutate any aguements that it's given.
-The advantage of pure functions is that whenever you give them a particular variable(s), they will always have the same output and effect.
-
-```js
-const square = x => x*x // ES6
-
-function square(x) { // ES5
- return x*x
-}
-```
-
-Functions that are not pure have less predictable effect - by definition, they mutate something, either something it's passed, or some variable outside of it's scope.
-
-```js
-var someThing = []
-
-function(x) {
- someThing.push(x) // this will mutate someThing outside of the function's scope
-
- return x++ // this will mutate the variable that was passed in
-}
-
-```
\ No newline at end of file
diff --git a/http/networking.md b/http/networking.md
deleted file mode 100644
index f2bdeda..0000000
--- a/http/networking.md
+++ /dev/null
@@ -1,31 +0,0 @@
-A server is often referred to as the physical or virtual machine. It's what responds when we visit a web site, sending us all the information our browser needs to display the site correctly.
-
-A service:
-
- - Just an application that runs on a particular computer
- - Listens for requests and then serves responses
- - A web server is a service which serves web pages
-
-Network addresses:
-
- - Same as IP address
- - The address of a computer on a network
- - An example is 192.168.1.45
- - The internet started running out of the old kind of addresses (IPv4), so now there's IPv6! These addresses look like this: `2001:4860:4860::8888`. They can include letters: `1fff:0:a88:85a3::ac1f`.
-
-Ports:
-
- - The particular 'door' at an address
- - The connection to the application/service, such as HTTP, that is listening for requests
-
-```
- IPv4 address port
- v v
- 192.168.20.30:80
- 192.168.20.30:3000
-
- IPv6 address port
- v v
- [2001:4860:4860::8888]:80
-```
-
diff --git a/http/params-intro.md b/http/params-intro.md
deleted file mode 100644
index b6d2580..0000000
--- a/http/params-intro.md
+++ /dev/null
@@ -1,50 +0,0 @@
-Params is short for parameters. These are one way to send information in a request. Params can be found in a couple of places and might be named differently depending on your framework.
-
-There are two kinds of params:
-
-#### Params in a query
-
-```js
-http://mycats.herokuapp.com/api/v1/cats?name=fluffy+joe&city=wellington
-```
-
-When the server receives this get request, if the request object is `req`, there will often be a way to access the query params. In Express.js, it's `req.query`, and the object returned would look like this:
-
-```js
-{
- name: 'fluffy joe',
- city: 'wellington'
-}
-```
-
-Ref: http://expressjs.com/en/api.html#req.query
-
-These types of params are used to filter the data returned from an HTTP GET request, not to send data to be saved by the server.
-
-
-#### Params in a route
-
-e.g.
-
-```js
-http://mycats.herokuapp.com/api/v1/cats/12/edit
-```
-
-On the server-side, it's common to set up routes to accept parameters. In this example the route definition would be:
-
-```js
-app.get('api/v1/cats/:id/edit', function(req, res) {
- console.log(req.params)
- //...
-})
-```
-
-Using Express.js, in the example above `req.params` would return:
-
-```js
-{
- id: 12
-}
-```
-
-Ref: http://expressjs.com/en/api.html#req.params
diff --git a/http/sending-request-url-data.md b/http/sending-request-url-data.md
new file mode 100644
index 0000000..bdfa2b5
--- /dev/null
+++ b/http/sending-request-url-data.md
@@ -0,0 +1,51 @@
+# Sending Request URL Data
+
+There are two ways to send data in the URL: the query string and route parameters.
+
+## Query String
+
+```
+GET http://mycats.herokuapp.com/api/v1/cats?name=fluffy+joe&city=wellington
+```
+
+When the server receives this GET request, if the request object is `req`, there will often be a way to access the query string. In Express, it's `req.query`, and the object returned would look like this:
+
+```js
+{
+ name: 'fluffy joe',
+ city: 'wellington'
+}
+```
+
+Reference: http://expressjs.com/en/api.html#req.query
+
+This type of data is used to filter the data returned from an HTTP GET request, not to send data to be saved by the server.
+
+
+## Route Parameters
+
+Consider this example:
+
+```
+GET http://mycats.herokuapp.com/api/v1/cats/12/edit
+```
+
+On the server-side, it's common to set up routes to accept parameters. In this example the route definition would be:
+
+```js
+app.get('api/v1/cats/:id/edit', (req, res) => {
+ console.log(req.params)
+ //...
+})
+```
+
+Using Express in the example above, `req.params` would return:
+
+```js
+{
+ id: 12
+}
+```
+
+Reference: http://expressjs.com/en/api.html#req.params
+
diff --git a/http/side-effects.md b/http/side-effects.md
deleted file mode 100644
index 91dfbac..0000000
--- a/http/side-effects.md
+++ /dev/null
@@ -1,6 +0,0 @@
-A `get` requests is a _read_ operation, and read operations shouldn't have _side effects_ - meaning, nothing should change as the result of just reading it. The parameters sent in the URL are called the _query_ part of the URL and are designed to be used to filter the data the request is requesting - not for saving data on the server.
-
-If you're sending data to the server to be saved, you expect side effects - the saving of the data. That's fine, you should just be more explicit in your intent - by using `post`.
-
-There are a lot of _shoulds_ in this topic. These are motivated by being a good HTTP citizen and using the protocol how it was intended. It is certainly possible to write `get` requests that have side effects, but adhering to this guidance will help you maintain expectations with other developers and illustrate your appreciation for the HTTP specification and its authors. This guidance will become even more important when we learn about REST web APIs.
-
diff --git a/http/status-codes.md b/http/status-codes.md
index 4454dbe..0c3b9c4 100644
--- a/http/status-codes.md
+++ b/http/status-codes.md
@@ -1,54 +1,59 @@
-It is important to always send back the appropriate status codes with your API response.
-The following HTTP status codes are possible in response to a request:
+# HTTP Status Codes
+
+It is important to always send back the appropriate status codes with your API response. The following table includes some of the possible HTTP status codes:
-
-
HTTP Status Code
-
Status
-
Description
-
-
-
-
200
-
OK (Immediate response)
-
The request was a success and the response includes the
-requested data.
-
-
-
-
202
-
OK (Immediate response)
-
The request was received and queued for processing, but not yet
-processed. Usually in the case of a POST request
-
-
-
-
400
-
Bad Request
-
The request was malformed or unexpected.
-
-
-
-
401
-
Unauthorized
-
The request did not include a valid API key
-
-
-
-
404
-
Not Found
-
The requested resource was not found.
-
-
-
429
-
Too Many Requests
-
The rate limit has been reached for this API key.
-
-
-
500
-
Internal Server Error
-
The request could not be fulfilled due to an unexpected
-error.
-
-
-
\ No newline at end of file
+
+
HTTP Status Code
+
Status
+
Description
+
+
+
+
+
200
+
OK (Immediate response)
+
The request was a success and the response includes the requested data.
+
+
+
+
202
+
OK (Immediate response)
+
The request was received and queued for processing, but not yet processed. Usually in the case of a POST request
+
+
+
+
400
+
Bad Request
+
The request was malformed or unexpected.
+
+
+
+
401
+
Unauthorized
+
The request did not include a valid API key
+
+
+
+
404
+
Not Found
+
The requested resource was not found.
+
+
+
+
429
+
Too Many Requests
+
The rate limit has been reached for this API key.
+
+
+
+
500
+
Internal Server Error
+
The request could not be fulfilled due to an unexpected error.
+
+
+
+
+
+For a more comprehensive list of status codes: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
+
diff --git a/http/the-web.md b/http/the-web.md
deleted file mode 100644
index e930721..0000000
--- a/http/the-web.md
+++ /dev/null
@@ -1,15 +0,0 @@
-The web is a subset of the wider internet. The parts, roughly speaking, are web sites you can visit with your browser. Examples of things on the internet that are not on the web:
-
- - Email
- - Skype
- - Bittorrent
-
-Protocols are agreements that define how different computers communicate with each other. For example:
-
- - TCP/IP (transmission control protocol/internet protocol)
- - VOIP (voice over internet protocol)
- - HTTP (hypter text transer protocol)
- - FTP (file transer protocol)
-
-DNS, the Domain Name Service, defines how domain names, such as devacademy.co.nz, are resolved to IP addresses, such as 12.57.211.43. This resolution is required before the computers are able to communicate with each other.
-
diff --git a/http/verbs.md b/http/verbs.md
deleted file mode 100644
index 2f949bd..0000000
--- a/http/verbs.md
+++ /dev/null
@@ -1,9 +0,0 @@
-The 4 most common HTTP requests (also called _verbs_ and _methods_) are:
-
-* GET: asks for an existing resource
-* POST: sends data to create a new resource
-* PUT: sends data to update existing resource
-* DELETE: asks for an existing resource to be deleted
-
-There are a few other HTTP verbs, but these are the important ones for now.
-
diff --git a/images/paint-by-numbers.jpg b/images/paint-by-numbers.jpg
deleted file mode 100644
index 0802164..0000000
Binary files a/images/paint-by-numbers.jpg and /dev/null differ
diff --git a/images/redux-overview.jpg b/images/redux-overview.jpg
deleted file mode 100644
index 0da7122..0000000
Binary files a/images/redux-overview.jpg and /dev/null differ
diff --git a/images/shoulders_of_giants.jpg b/images/shoulders_of_giants.jpg
deleted file mode 100644
index d6e82e4..0000000
Binary files a/images/shoulders_of_giants.jpg and /dev/null differ
diff --git a/javascript/data-structures.md b/javascript/data-structures.md
deleted file mode 100644
index 0f51a6c..0000000
--- a/javascript/data-structures.md
+++ /dev/null
@@ -1,56 +0,0 @@
-You need to be able to navigate complicated nested data structures.
-When you ask questions of servers on the internet, you're going to get complicated responses, like:
-
-```js
-{
- "statusCode": 200,
- "path": "users/subscriptions",
- "query": {
- "basePlan": "standard",
- "totalGreaterThan": 400
- },
- "results": [
- {
- "id": 201,
- "name": "Rinsed Ltd",
- "email": "rinsed@gmail.com",
- "basePlan": "standard",
- "xeroPlan": "starter",
- "addOns": {
- "gstReview": 20,
- "companyAdvice": 75
- }
- },{
- "id": 332,
- "name": "Loomio Cooperative Ltd",
- "email": "accounts@loomio.org",
- "basePlan": "social enterprise",
- "xeroPlan": "starter",
- "addOns": {
- "extraSoftware": 10,
- "gstReview": 5
- }
- }
- ]
-}
-```
-
-You might like to play with ways of explore this data structure in the Node REPL.
-
-Note: REPL stands for "Read Evaluate Print Loop". When you have node installed and you type `node` in your terminal, you'll enter a simple interactive programming sandbox where you can play with JavaScript directly (type Ctrl-C twice to exit.) The console on your browser is another type of a REPL that provides access to the browser's DOM rather than the Node.js library.
-
-Try **chaining** property calls and navigating the data structure. For example:
-
-```js
-results.query.totalGreaterThan
-```
-
-If an object is too deep you can also tell it to give you its keys using the method `Object.keys()`. For example:
-
-```js
-Object.keys(response)
-Object.keys(response.query)
-```
-
-You will encounter a lot of objects like this over the next few weeks. It's important to not be scared off, to feel comfortable exploring them. Try different approaches to get information out of objects.
-
diff --git a/javascript/datatypes.md b/javascript/datatypes.md
deleted file mode 100644
index 1108af7..0000000
--- a/javascript/datatypes.md
+++ /dev/null
@@ -1,11 +0,0 @@
-* Primitives
- - Boolean
- - Null
- - Undefined
- - Number
- - String
-* Objects
- - Special types of objects
-
-The Mozilla Developer Network has a really good [explanation of JavaScript data types](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures).
-
diff --git a/javascript/es6-syntax-1.md b/javascript/es6-syntax-1.md
deleted file mode 100644
index b59929e..0000000
--- a/javascript/es6-syntax-1.md
+++ /dev/null
@@ -1,120 +0,0 @@
-While exploring the new ES6 syntax, you might consider using the Babel CLI (command line interface) tools. These provide a REPL (read evaluate print loop) interface and let you run files in the terminal. Use npm to install them:
-
-```sh
-npm install -g babel-cli
-```
-
-See [Babel CLI tools](https://babeljs.io/docs/usage/cli/) for more information.
-
-
-### Modules
-
-Modules provide a way to separate our code across multiple files. This makes our applications much easier to maintain and easier for multiple developers to work on at the same time. This new language feature does the same thing `module.exports` and `require` perform in the Node.js environment.
-
-To export values, objects, arrays, function, or pretty much anything from a module, just preface it with `export`.
-
-```js
-// utility.js
-export default function joinStrings (s1, s2) {
- return s1 + ' ' + s2
-}
-```
-
-This makes it available to _import_. There are multiple ways to import items from modules. To import default values like the `joinStrings` function above:
-
-```js
-// app.js
-import join from 'utility.js'
-var combined = join('pretty', 'cool')
-```
-
-For more information, see [ES6 In Depth: Modules](https://hacks.mozilla.org/2015/08/es6-in-depth-modules/).
-
-
-### Variable declaration with `let` and `const`
-
-In ES5, we use `var` to declare variables. Variables declared with `var` are available to the entire function regardless of where it is defined. This is not true for most languages, which have _block-level_ scoping, rather than _function-level_ scoping. `let` and `const` apply block level scoping to JavaScript. This means we can define variables inside `if` statements and `for` loops (and other block constructs) that are not available outside of the blocks they are defined in. `const` defines a variable that cannot be reassigned with a different value. For example:
-
-```js
-function testVar () {
- var foo = 44
- if (true) {
- var foo = 13 // same variable
- console.log(foo) // 13
- }
- console.log(foo) // 13
-}
-
-function testLet () {
- let foo = 44
- if (true) {
- let foo = 13 // different variable
- console.log(foo) // 13
- }
- console.log(foo) // 44
-}
-```
-
-For more information, check out [ES6 In Depth: let and const](https://hacks.mozilla.org/2015/07/es6-in-depth-let-and-const/).
-
-
-### Arrow functions
-
-Arrow functions are a new syntax to write anonymous functions. So far we've been writing:
-
-```js
-var fn = function (op1, op2) {
- return op1 + op2
-}
-```
-
-With ES6 arrow functions, we can write:
-
-```js
-const fn = (op1, op2) => op1 + op2
-```
-
-It essentially removes the `function` keyword and places the arrow between the parameters and the body of the function.
-
-Some notes about arrow functions:
-
-* The parentheses are optional around the parameters if there is only a single parameter. They are required if there are no parameters or more than one.
-
-* Curly braces are optional when the body of the function can fit on one line.
-
-* If there are no curly braces, arrow functions automatically return the result of the statement to the right of the arrow. This is called _implicit_ return.
-
-* If there are curly braces, we still need to use the `return` keyword:
-
-```js
-// Doesn't need return
-const fn1 = (op1, op2) => op1 - op2
-
-// Needs return
-const fn2 = (op1, op2) => { return op1 - op2 }
-```
-
-For more information, check out [ES6 In Depth: Arrow functions](https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/).
-
-
-### Template Strings
-
-String interpolation provides a much nicer way to combine strings and values. We're currently used to concatenating strings when we need to combine them:
-
-```js
-var user = {name: 'Kristina'}
-var welcome = 'Welcome back ' + user.name + '. Good to see you.'
-```
-
-The new syntax is easier to read:
-
-```js
-const user = {name: 'Kristina'}
-const welcome = `Welcome back ${user.name}. Good to see you.`
-```
-
-Notice how the string is deliniated with backticks to indicate it is a template string.
-
-For more information, check out [ES6 In Depth](https://hacks.mozilla.org/2015/05/es6-in-depth-template-strings-2/).
-
-There is a lot more about ES6 to learn, but that is enough for now. Feel free to explore - there are a lot of really nice additions. There are really good resources on ES6/2015 online.
diff --git a/javascript/first-class-functions.md b/javascript/first-class-functions.md
deleted file mode 100644
index 41e0984..0000000
--- a/javascript/first-class-functions.md
+++ /dev/null
@@ -1,42 +0,0 @@
-An important thing to remember about functions in JavaScript is: *functions are values*.
-
-This means that functions are treated as first-class citizens, just like numbers and objects. They have all the properties we expect of other objects. Check out Helen Emerson's [article on the subject](http://helephant.com/2008/08/19/functions-are-first-class-objects-in-javascript/) for a more in-depth explanation.
-
-Let's look at this example:
-
-```js
-// A named function
-function triple (x) {
- return x * 3
-}
-
-// An anonymous function
-function (x) {
- return x * 3
-}
-
-// An anonymous function assigned to a variable
-var triple = function (x) {
- return x * 3
-}
-```
-
-Because the last example uses a variable, you can do some cool things like this:
-
-```js
-var engorgio = triple
-var value = engorgio(30) // value is 90
-```
-
-Both `triple` and `engorgio` refer to the same function. But the fun does not stop there! We can also pass functions into other functions as arguments.
-
-A good example of this is the filter function, probably the most basic and useful higher order function. It's a function that operates on an array, and accepts another function as an argument that it uses to return a new filtered version of the array.
-
-Let's pop over to this repl.it and have a play: [https://repl.it/CGjq](https://repl.it/CGjq/26).
-
-So, to recap:
-
-* We can store functions in variables
-* We can store functions as properties of other objects
-* Functions can have properties
-* We can pass functions as arguments into other functions
diff --git a/javascript/sets.md b/javascript/sets.md
deleted file mode 100644
index e69de29..0000000
diff --git a/mobile/debugging.md b/mobile/debugging.md
index c561800..49f9f31 100644
--- a/mobile/debugging.md
+++ b/mobile/debugging.md
@@ -6,6 +6,7 @@ So what does mobile first actually look like in a development practice context?
Luckily we have lots of fabulous tools to help us!
+
## Stylesheets
Let's just spend a quick moment on stylesheets.
@@ -17,6 +18,7 @@ Kotare's final project did a really good job of mobile first approach,
- [tandem](https://github.com/Tandem-NZ/tandem/blob/master/public/styles/sass/_desktop.scss)
+
## Debugging mobile
There are loads of different ways we can debug and play with mobile, the first is obviosuly to shrink our browsers to size. However, that can sometimes not work.
@@ -50,7 +52,6 @@ This works for any ios devices, so all the ipads ect, which is SUPER USEFUL!
http://appletoolbox.com/2014/05/use-web-inspector-debug-mobile-safari/
-
Xcode also has a new simulator, though this is only for iphone 6 and above
- open xcode
@@ -63,8 +64,10 @@ Pretty much exactly the same applies with Chrome and android devices. In the pho
here is a useful blog on how to do this:
https://developer.chrome.com/devtools/docs/remote-debugging
+
## Extra excitment, demo-ing your mobile things on desktop
- Have your iphone plugged in
- Open quicktime player on your mac
-- select the little arrow on the dropdown, and select your phone
\ No newline at end of file
+- select the little arrow on the dropdown, and select your phone
+
diff --git a/oo/classes.md b/oo/classes.md
index ef7cfdb..deecc5e 100644
--- a/oo/classes.md
+++ b/oo/classes.md
@@ -1,11 +1,14 @@
-In Javascript, classes have only just been added with ES6.
-Check out the docs here : https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes, in particular :
+# Classes
+
+In JavaScript, classes have only just been added with ES6. Check out the docs here: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes, in particular:
+
- constructor
- prototype methods
- extends (note sub-classing is another way to say inheritance)
- super
-#### Using classes in your code
+
+## Using classes in your code
You'll need to transpile (convert) your new ES6 standard code into code that all browsers will support.
@@ -30,5 +33,5 @@ var OrangeTree = require('../OrangeTree')
import OrangeTree from '../OrangeTree'
import {pruneTree} from '../OrangeTree'
+```
-```
\ No newline at end of file
diff --git a/oo/classical-inheritance-es5.md b/oo/classical-inheritance-es5.md
index 0547788..4b7c5c7 100644
--- a/oo/classical-inheritance-es5.md
+++ b/oo/classical-inheritance-es5.md
@@ -1,7 +1,10 @@
+# Pseudo-classical Inheritance (ES5)
+
Many programming languages use the concepts of `class`, `subclass` and `inheritance` to assist with code reuse. When we create objects of a particular subclass these objects inherit properties and methods from their parent class. This allows us to write code once on the parent class and have it inherited and reused on its descendants.
JavaScript ES5 does not implement "classical inheritance" in the same way as other languages. Instead its common to use "prototypal inheritance" to mimic classical inheritance with constructor functions. Its also possible to use factory functions to implement inheritance. As these are not true classes we sometimes call these "pseudo-classes". The examples below show how to implement the classical inheritance pattern with the tools available in ES5:
+
## Prototypal inheritance with constructor functions
```js
@@ -60,7 +63,6 @@ console.log(frodoComment === oneRingDiscussion.getCommentAtIndex(0))
console.log(frodoComment instanceof Comment)
// true
-
```
The code above implements a parent constructor function `Post` and its two child constructor functions `Discussion` and `Comment`. We might imagine that this code drives an online discussion forum. `Post` has three properties `author`, `content` and `createdAt` and one method `getCreatedAt()`. When we define `Comment` and `Discussion` we call the parent constructor method passiing in a reference the current context `this` and the child's `arguments`. This lets `Discussion` and `Comment` inherit `Post`'s properties and the `getCreatedAt()` method (this is equivalent to calling `super` in ES6). Child constructor functions can also implement their own properties and methods.
@@ -134,14 +136,14 @@ console.log(frodoComment instanceof Comment)
// false
console.log(frodoComment instanceof Object)
// true
-
```
+
## Differences
We call Constructor functions using the `new` keyword while we call factory functions like regular functions. Constructor function instances can be checked against their constructor with the `instanceof` keyword while factory function instances are regular `Object` instances.
-The more informative `instanceof` behaviour of constructor functions may be useful in codebases where checking the pseudo-class of instances is important for error catching, e.g.:
+The more informative `instanceof` behaviour of constructor functions may be useful in codebases where checking the pseudo-class of instances is important for error catching, for example:
```js
Discussion.prototype.addComment = function (comment) {
@@ -152,6 +154,7 @@ Discussion.prototype.addComment = function (comment) {
}
```
+
## Further Information
* [http://javascript.crockford.com/inheritance.html](http://javascript.crockford.com/inheritance.html)
@@ -162,3 +165,4 @@ Discussion.prototype.addComment = function (comment) {
* [Factory constructor pattern](http://javascript.info/tutorial/factory-constructor-pattern)
* [Defending constructors](http://www.2ality.com/2013/07/defending-constructors.html)
* [instanceof](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/instanceof)
+
diff --git a/oo/classical-inheritance-es6.md b/oo/classical-inheritance-es6.md
index f60a2b8..da1762a 100644
--- a/oo/classical-inheritance-es6.md
+++ b/oo/classical-inheritance-es6.md
@@ -1,44 +1,46 @@
+# Pseudo-classical Inheritance (ES6)
+
ES6 introduced the `class` and `extends` and `super` keywords. These keywords provide another way to express [prototypal inheritance](https://developer.mozilla.org/en/docs/Web/JavaScript/Inheritance_and_the_prototype_chain) using a syntax that may be more familiar to developers accustomed to it in many other programming languages. An example is shown below:
## Example
```js
class Post {
- constructor(options) {
+ constructor (options) {
const { author, content } = options
this.author = author
this.content = content
this.createdAt = Date.now()
}
- getCreatedAt() {
+ getCreatedAt () {
return this.createdAt
}
}
class Comment extends Post {
- constructor(options) {
+ constructor (options) {
super(options)
this.likeCount = 0
}
- like() {
+ like () {
this.likeCount ++
}
}
class Discussion extends Post {
- constructor(options) {
+ constructor (options) {
super(options)
this.title = options.title
this.comments = []
}
- addComment(comment) {
+ addComment (comment) {
this.comments.push(comment)
}
- getCommentAtIndex(index) {
+ getCommentAtIndex (index) {
return this.comments[index]
}
}
@@ -54,42 +56,48 @@ const frodoComment = new Comment({
content: 'One idea is to throw it into a volcano. What does everyone think?'
})
-
console.log(frodoComment.getCreatedAt())
oneRingdiscussion.addComment(frodoComment)
console.log(frodoComment === oneRingDiscussion.getCommentAtIndex(0))
// => true
-
```
+
The code above implements a parent class `Post` and its two child classes `Discussion` and `Comment`. We might imagine that this code drives an online discussion forum. `Post` has three properties `author`, `content` and `createdAt` and one method `getCreatedAt()`. When we define `Comment` and `Discussion` we use the `extends` keword to inherit `Post`'s properties and the `getCreatedAt()` method. These child classes can also implement their own properties and methods.
Inside each of the child classes' `constructor()` we can see the usage of `super`:
+
```js
// class definition
-constructor(options) {
+constructor (options) {
super(options)
// more constructor code
}
-
```
+
The `super(options)` call respresents *the parent class's contructor method*:
+
```js
class Post {
- constructor(options) {
+ constructor (options) {
const { author, content } = options
this.author = author
this.content = content
this.createdAt = Date.now()
}
-// more code
+ // more code
+}
```
+
This means that whenever we instantiate a `Comment` or `Discussion` passing in our options object we also register it with `author`, `content` and `createdAt` properties.
+
## Applications
React.js uses a `Component` class for [one of its methods](https://facebook.github.io/react/docs/reusable-components.html#es6-classes) for creating UI components.
+
## Further Information
* [MDN - Classes](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes)
* Dan Abramov outlines some [best practices](https://medium.com/@dan_abramov/how-to-use-classes-and-sleep-at-night-9af8de78ccb4#.wdmybk5py) for using the `class` keyword in JavaScript
+
diff --git a/oo/constructors.md b/oo/constructors.md
index 47e01cd..3c6962c 100644
--- a/oo/constructors.md
+++ b/oo/constructors.md
@@ -1,13 +1,15 @@
+# Constructors
+
Constructors are similar to Factory functions but slightly different.
-e.g.
+For example,
```js
-var Person = function(name) {
+var Person = function (name) {
this.name = name
}
-Person.prototype.sayHello = function() {
+Person.prototype.sayHello = function () {
console.log("Hello, I'm " + this.name)
}
@@ -23,4 +25,5 @@ We call constructors using the keyword `new` which instantiates a new instance o
Note we've also extending the Person prototype with a function (`sayHello`).
-Constructors are slightly faster than Factory functions, but there are a few gotchas that mean they're currently less popular.
\ No newline at end of file
+Constructors are slightly faster than factory functions, but there are a few gotchas that mean they're currently less popular. _**LIKE WHAT?**_
+
diff --git a/oo/factory-functions.md b/oo/factory-functions.md
index f068eab..e3e8b68 100644
--- a/oo/factory-functions.md
+++ b/oo/factory-functions.md
@@ -1,13 +1,13 @@
-Like a closure, but returns an object.
-You can store details, prep the layout, and attach functions to your object.
+# Factory Functions
+
+Like a closure, but returns an object. You can store details, prep the layout, and attach functions to your object.
```js
-function personFactory(name) {
+function personFactory (name) {
return {
name: name,
age: undefined,
- introduceYourself: function() {
- return `Hi, my name is ${name}`
+ introduceYourself: () => `Hi, my name is ${name}`
}
}
}
@@ -19,3 +19,4 @@ console.log(vanessa.introduceYourself())
```
There's a small detail where if you are making more than 10,000 objects with a factory function, you should consider moving to classes, which start to be more performant in that range (more on this later).
+
diff --git a/oo/intro.md b/oo/intro.md
index dfc4072..5a97fc2 100644
--- a/oo/intro.md
+++ b/oo/intro.md
@@ -1,6 +1,8 @@
-Object Oriented programming (OO) is a pattern of organising code that involves thinking about the things you're dealing as being **instances** of particular objects.
+# An Introduction to Object-orientation
-We often want to store particular details (**state**) and perform particulr actions (**behvaiour**) which are just relevant to a particular type of this, OO allows us to pull all this together in one place.
+Object Oriented programming (OOP) is a pattern of organising code that involves thinking about the things you're dealing as being **instances** of particular objects.
+
+We often want to store particular details (**state**) and perform particular actions (**behaviour**) which are just relevant to a particular type of this, OO allows us to pull all this together in one place.
For example, all instances of a `User` object might have a particular state (e.g. name, email, isAwake) and have particular methods you could call on that user, e.g. if `piet` is an instance of `User`, you could call `piet.getEmail()` or `piet.wakeUp()`, or `piet.introduceYourself(dave)`.
@@ -9,15 +11,15 @@ If you're ever wondering which object should own a function, you can ask yoursel
> Should this thing know about this concept, is it this object's responsibility?
-e.g. Should I be able to ask a Cat what it's email is? ... No, that's that's Owner that has an eamil. I should be able to ask Cat about it's owner, and ask owner about it's email.
+For example, should I be able to ask a Cat what its email is? No, it's the Owner that has an email. I should be able to ask Cat about its owner, and ask Owner about its email.
-#### Prototype-based OO
+## Prototype-based OO
-Constructors are the prototype-way to do OO in javascript.
+Constructors are the prototype-way to do OO in JavaScript.
-#### Class-based OO
+## Class-based OO
Classes are similar to Constructors, but they have a number of additional features:
- **inheritance** : classes can inherit from / extend existing classes
@@ -31,3 +33,4 @@ Classes are similar to Constructors, but they have a number of additional featur
- instantiate
- state + behaviour
- prototype (like a template)
+
diff --git a/oo/methods.md b/oo/methods.md
deleted file mode 100644
index 0c43e79..0000000
--- a/oo/methods.md
+++ /dev/null
@@ -1,2 +0,0 @@
-Functions that belong to instances of classes are called methods.
-e.g. A `User` object `dave` has a method on it called `email` which can be called : `dave.email()`
\ No newline at end of file
diff --git a/oo/the-journey.md b/oo/the-journey.md
index a79fa2a..4349863 100644
--- a/oo/the-journey.md
+++ b/oo/the-journey.md
@@ -286,3 +286,4 @@ const squareClass = new SquareClass(10, 'red')
*
*
+
diff --git a/projects/group-projects-introduction.md b/projects/group-projects-introduction.md
deleted file mode 100644
index c78b4b2..0000000
--- a/projects/group-projects-introduction.md
+++ /dev/null
@@ -1,14 +0,0 @@
-Today we will spend a bit of time thinking about how we will build our group projects. You should try to use as much of what you've learned this week in your project. You'll have 3 or 4 people on your team and you're expected to partition the work among team members. Each team member may want to choose a task they are strong in, or a task that will solidify knowledge for them. The rest of the team should support these decisions as much as it makes sense. You may also consider designating certain team members as: Time Keeper and Git Keeper (you can come up with your own inventive names for these positions!)
-
-You can use today to establish teams and scope out what you're going to build. A teacher should approve your project idea before you begin. During your planning, you should define milestones and (at a minimum) commit to your repo at each milestone. You are expected to build the appropriate parts using Test Driven Development (branch, red, green, refactor, diff, commit).
-
-Feature freeze is the time when you are not permitted to work on any new functionality. Code freeze is when you're not permitted to make any more changes to your codebase. Feature freeze is at 3:30 and code freeze is at 4pm. Presentations begin promptly at 4:30. Each team member should speak during the presentation. Each team will have 5 minutes to describe what you've built, show a demonstration, and possibly show one piece of code that is particularly interesting.
-
-
-### Team dynamics
-
-You've been pair programming for a couple of weeks now, but this is the first time you're going to build something on a team. Be sure you remain mindful during your group project. You're going to be under pressure to finish something under a time limit. You're going to want it to be great and something you can be proud of, and this could add to the pressure. You're going to need to depend on your teammates. Sometimes they won't disappoint you, and sometimes they will. How you react is up to you.
-
-Remember to have **I**ntegrity, **K**indness, and **E**ffort. Be open and honest with yourself and your team. Try to minimize surprises by being transparent. Keep the communication levels high and ask for help when you need it. Focus on setting up your teammates for success. And have fun!
-
-These group projects are as much about how you work together as what you build.
diff --git a/projects/personal-projects-introduction.md b/projects/personal-projects-introduction.md
deleted file mode 100644
index 642e5ef..0000000
--- a/projects/personal-projects-introduction.md
+++ /dev/null
@@ -1,35 +0,0 @@
-> "Whatever course you decide upon, there is always someone to tell you that you are wrong. There are always difficulties arising which tempt you to believe that your critics are right. To map out a course of action and follow it to an end requires courage." ~ Ralph Waldo Emerson
-
-## Purpose
-
-Many developers work on side projects as a funnel for both professional development and meaningful play. Some employers (most famously Google) even alot time each month for their employees to work on projects that interest them. It's a great way to cement your understanding of new tools and things we've learned during the first part of the bootcamp.
-
-It's also a good time to explore _how_ you learn. What works best for you? When you're working alone, how can you make best use of the time to further your understanding?
-
-
-## Tips
-
- - Explore something you care about.
- - Build something you or someone you know would love to use.
- - Integrate new tools and techniques as you learn them.
-
-The most impressive apps that have been developed in this phase were built with continuous improvement in mind. First, create a minimum viable product (MVP) as soon as possible. It doesn't have to be fancy! Early MVP is a powerful tool in developing your project. It provides reassurance ("At least I have _this_ done!") and it can help to keep your scope controlled: not biting off too much work all at once! Your MVP should be fairly simple; once you have your MVP, your project can develop in complexity over the three weeks of Phase 2.
-
-
-## Process
-
-There will be time set aside each week to work on personal projects, but you may choose to use your own time to work on it as well. At the end of Phase 2 everyone will present their project to the rest of the cohort.
-
-
-## Examples
-
-Here are some examples from previous cohorts:
-
- - [Trout-trout](http://trout-trout.herokuapp.com/#!/), an app to track trout caught in a lake
-(repo found [here](https://github.com/SamSimmons/garyTrout))
-
- - [Schools project](https://github.com/wishmouse/schools)
-
- - [Hear now gone tomorrow](https://github.com/KeakOne/hearnow-gonetommorow)
-
- - [Ki Mai](http://ki-mai.herokuapp.com/users) ([github](https://github.com/tony-luisi/ki_mai)), an interactive chat application to aid in learning the Maori language.
diff --git a/react/components.md b/react/components.md
deleted file mode 100644
index e3c0b25..0000000
--- a/react/components.md
+++ /dev/null
@@ -1,40 +0,0 @@
-React forces you to think about your user interfaces as sets of _components_: small composable areas of the view. Components are composed in a hierarchical structure with _container components_ acting as parents of _child components_. Each component is made up of the user interface elements (JSX) and data. The guidance is to deconstruct your views into components and understand what data they contain before you begin building your user interface.
-
-This is an example of a component:
-
-```js
-// Header.jsx
-import React from 'react'
-
-class Header extends React.Component {
- render() {
- return (
-
-
Header
-
- )
- }
-}
-
-export default Header
-```
-
-This component will be imported into the app using:
-
-```js
-// App.jsx
-import React from 'react'
-import Header from './Header'
-
-class App extends React.Component {
- render() {
- return (
-
-
-
- )
- }
-}
-
-export default App
-```
diff --git a/react/event-delegation.md b/react/event-delegation.md
deleted file mode 100644
index e7ac7eb..0000000
--- a/react/event-delegation.md
+++ /dev/null
@@ -1,69 +0,0 @@
-In order to respond to user events, component functions can be bound to [virtual] DOM events. In this example, an `addToCart` function in the `` component is called when a button is clicked in the `` component.
-
-```js
-// ItemList.js
-import React from 'react'
-import Item from './Item'
-
-class ItemList extends React.Component {
-
- constructor(props) {
- super(props)
- this.addToCart = this.addToCart.bind(this)
- }
-
- addToCart (itemID) {
- console.log(itemID)
- }
-
- render () {
- return (
-
- )
- },
-}
-
-export default ItemList
-```
-
-Notice how the local `addToCart` function is being passed as a prop to the `` component. Additionally, notice how an `itemID` argument is passed to the `addToCart` function. This is how the parent component knows which item we are adding to the cart.
-
-```js
-// Item.js
-import React from 'react'
-
-class Item extends React.Component {
-
- constructor(props) {
- super(props)
- this.handleClick = this.handleClick.bind(this)
- }
-
- handleClick () {
- this.props.addToCart(this.props.id)
- }
-
- render () {
- return (
-
-
{this.props.name}
-
-
- )
- }
-}
-
-export default Item
-```
-
-The `addToCart` event handler is used directly from `this.props` in Item.js.
-
diff --git a/react/forms.md b/react/forms.md
deleted file mode 100644
index b640215..0000000
--- a/react/forms.md
+++ /dev/null
@@ -1,195 +0,0 @@
-Sometimes forms in React can feel like a bit of a stumbling block, but they needn't be. Like most of the content you've learned so far, with practice they become far less intimidating!
-
-
-## Where does the data go?
-
-There are various approaches to handling forms, but mostly they boil down to one decision: where do you want to keep the form data?
-
- - in _component state_ (controlled components)
- - in the _DOM_, using refs (uncontrolled components)
- - in the _Redux store_ (if you haven't encountered Redux yet, don't worry about this one!)
-
-As usual on the Internet, lots of people have very strong opinions about how to write forms! Facebook [recommends](https://facebook.github.io/react/docs/forms.html#alternatives-to-controlled-components) using controlled components for the most part, but not everyone agrees. [This comparison of the approaches](https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/) is a fair summary.
-
-We suggest not getting too tangled up in the debate. Learn the different ways to work with forms, then pick the one that you think fits your need best. If it ends up not working so well for you, revisit this decision with your team to talk about what could have been improved.
-
-If you want a rule of thumb, here's one:
-
- - if your form is relatively simple, try using refs;
- - if it's complicated or likely to become so, try using controlled components.
-
-
-## Uncontrolled components
-
-Here's an example of an uncontrolled component form:
-
-```js
- render () {
- return (
-
- )
- }
-```
-
-Each form element has a `ref` prop to which is assigned a very short anonymous function, setting whatever is passed to it as a property on `this` (the component). Using this approach, the value is grabbed from the element on the DOM and assigned to the component. We don't have to define `this.name` and `this.description`, they're just places to keep the form data until we're ready to submit it. (Although you should take care not to choose names like `render` or anything that might conflict with existing properties on your component!)
-
-But here's the thing: there's actually no need for the `
-```
-
-Notice that (unlike the uncontrolled example) this one has a `value` prop on each form element. This means that whatever is in the component state at that location will also be shown in the form.
-
-
-## Change handlers
-
-Each input also has an `onChange` prop which calls the `handleChange` function each time the user types a key. Take a look at how we could define it:
-
-```js
- handleChange (evt) {
- const field = evt.target.name
- this.setState({
- item: {
- ...this.state.item,
- [field]: evt.target.value
- }
- })
- }
-```
-
-If you haven't seen this sort of thing before, it's called [computed property name](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names) syntax (combined with the [object spread operator](http://redux.js.org/docs/recipes/UsingObjectSpreadOperator.html). Whatever string the variable `field` contains will become the property name. So:
-
-```js
- {
- ...this.state.item,
- [evt.target.name]: evt.target.value
- }
-```
-
-is just syntactic sugar for:
-
-```js
- const setField = {}
- setField[evt.target.name] = evt.target.value
- Object.assign({}, this.state.item, setField)
-```
-
-After your form submission, the item will look like this in state:
-
-```js
- {
- name: 'Wombat',
- description: 'Awesome furry creature with square poop.'
- }
-```
-
-
-## Submit handlers
-
-All the submit handler really has to do is send the form state back to the parent component. Here we've also reset the form by returning its state properties to empty strings:
-
-```js
- handleSubmit (evt) {
- evt.preventDefault()
-
- this.props.saveItem(this.state.item)
- this.setState({
- item: {
- name: '',
- description: ''
- }
- })
- }
-```
-
-What about validation? Well, we could check each property and make sure it wasn't empty:
-
-```js
- const { name, description } = this.state.item
- if (name.length && description.length) {
- this.props.saveItem(this.state.item)
- }
-```
-
-Once it gets much more complex than that, you'll need to decide whether to continue writing your own form logic or relying on an existing library to do it for you.
diff --git a/react/jsx.md b/react/jsx.md
index 48d6453..5c1c24d 100644
--- a/react/jsx.md
+++ b/react/jsx.md
@@ -1,3 +1,5 @@
+# JSX
+
JSX is a syntax extension to JavaScript which can be thought of as a hybrid between HTML and JavaScript:
```js
@@ -90,3 +92,4 @@ render () {
}
```
For more information, the React documentation introducing JSX is a great read: https://facebook.github.io/react/docs/introducing-jsx.html
+
diff --git a/react/lifecycle-methods.md b/react/lifecycle-methods.md
deleted file mode 100644
index 3d0ce5d..0000000
--- a/react/lifecycle-methods.md
+++ /dev/null
@@ -1,12 +0,0 @@
-When defining a stateful component in React, at least two methods are required: `constructor(props)`, and `render()`.
-
-There are other methods you can add which React components will pick up and use during the 'lifecycle' of a component.
-Read about them here : https://facebook.github.io/react/docs/component-specs.html#lifecycle-methods
-
-Lifecycle in this context refers to the different stages of an instantiated components life, from birth and attachment, to updating, through to 'death'.
-The most important to start with are :
- - `componentWillMount` - before render
- - `componentDidMount` - after render (and has been mounted)
- - `componentWillUnmount` - before unmount
-
-Here's a basic flow chart which might help : http://javascript.tutorialhorizon.com/2014/09/13/execution-sequence-of-a-react-components-lifecycle-methods/
\ No newline at end of file
diff --git a/react/lifecycle.md b/react/lifecycle.md
deleted file mode 100644
index 43cc923..0000000
--- a/react/lifecycle.md
+++ /dev/null
@@ -1,17 +0,0 @@
-React provides a few component methods that are called at various times throughout a component's lifetime.
-
-* `componentWillMount` is invoked once, immediately before the initial rendering occurs.
-
-* `componentDidMount` is invoked once, immediately after the initial rendering occurs.
-
-* `componentWillReceiveProps` is invoked when the component is receiving new props.
-
-* `shouldComponentUpdate` is invoked before rendering when new props or state is being received. If this function returns `false`, the `render` method will not be invoked as a result of this update.
-
-* `componentWillUpdate` is invoked before rendering when new props or state is being received.
-
-* `componentDidUpdate` is invoked immediately after the component's update have been rendered.
-
-* `componentWillUnmount` is invoked immediately before a component is unmounted from the DOM.
-
-For more information, see the [Component Specs and Lifecycle](https://facebook.github.io/react/docs/component-specs.html) article in the React documentation.
diff --git a/react/props.md b/react/props.md
deleted file mode 100644
index fbac3bc..0000000
--- a/react/props.md
+++ /dev/null
@@ -1,38 +0,0 @@
-Components receive their data in the form of props. If we wanted to make the header text of the example above more flexible, we could pass the text as a prop.
-
-```js
-// Header.jsx
-import React from 'react'
-
-class Header extends React.Component {
- render() {
- return (
-
-
{this.props.text}
-
- )
- }
-}
-
-export default Header
-```
-
-Notice how it is using `this.props.text` to get the value. This prop is passed in using what looks like an HTML attribute of the same name, `text`. Props can be named anything that is a valid JavaScript identifier.
-
-```js
-// App.jsx
-import React from 'react'
-import Header from './Header'
-
-class App extends React.Component {
- render() {
- return (
-
-
-
- )
- }
-}
-
-export default App
-```
diff --git a/react/react-intro.md b/react/react-intro.md
deleted file mode 100644
index 9df1bbc..0000000
--- a/react/react-intro.md
+++ /dev/null
@@ -1,3 +0,0 @@
-React was built by Facebook and is a JavaScript library for building user interfaces. There are a lot requirements when building a client-side web user interface that behaves like a native application. Many frameworks such as Backbone.js and Angular.js aim to address all of these requirements. React has chosen a different approach and focuses predominately on constructing the view. For example, it does not directly address routing or making API calls.
-
-React has also taken a very innovative approach to how it builds the user interface by abstracting away the user interface technology - on the web this is the DOM - so it can build the view intelligently. Making changes to the DOM creates a lot of work for web browsers. The more changes you make, the harder it has to work. React's approach is to do all of the hard work in the virtual DOM.
diff --git a/react/resources.md b/react/resources.md
index a77dcf4..7bdb53e 100644
--- a/react/resources.md
+++ b/react/resources.md
@@ -1,21 +1,24 @@
-- Really clear introduction to the fundamentals of React:
+# React Resources
+
+* Really clear introduction to the fundamentals of React:
- http://blog.andrewray.me/reactjs-for-stupid-people/
-- Two good egghead tutorials - the one with the Kiwi accent is an EDA Alumni! :
+* Two good egghead tutorials - the one with the Kiwi accent is an EDA Alumni! :
-https://egghead.io/lessons/react-react-fundamentals-development-environment-setup
-https://egghead.io/lessons/react-core-concepts-of-react-components-props-and-state
-- Fairly inclusive React course:
+* Fairly inclusive React course:
- http://reactjsprogram.teachable.com/courses/reactjsfundamentals
-- Blog post taking you through full stack react project
+* Blog post taking you through full stack react project
- http://teropa.info/blog/2015/09/10/full-stack-redux-tutorial.html#client-project-setup
-- Nice Youtube intro playlist for React:
+* Nice Youtube intro playlist for React:
- https://www.youtube.com/watch?v=4ZAEBxGipoA&list=PL6gx4Cwl9DGBhLZx_5C-jqECBE4HIID_k
-- Good blog focusing on the state idea in react:
+* Good blog focusing on the state idea in react:
- https://www.toptal.com/react/managing-view-state-with-react
-- A WHOLE load of react resources:
- - https://github.com/enaqx/awesome-react
\ No newline at end of file
+* A WHOLE load of react resources:
+ - https://github.com/enaqx/awesome-react
+
diff --git a/react/routing.md b/react/routing.md
deleted file mode 100644
index d9c4c3a..0000000
--- a/react/routing.md
+++ /dev/null
@@ -1,153 +0,0 @@
-When we start making single-page apps with dynamic interfaces (using React, Angular, Ember amongst others) we don't want to reload the page. But we still want the URL to reflect which part of the UI a user is looking at. This is often called the _view_.
-
-When the view changes, the user sees a different URL. The URL can be linked to from outside the site and the browser will load the correct view. However, the page is only loaded from the server _once_: everything else is done client-side, with API requests to communicate with the server as required.
-
-In React, we can manage client-side routing using [React Router](https://github.com/ReactTraining/react-router).
-
-
-### Routing to components
-
-We're going to be using React Router on the web (it can also be used in other environments) so we're going to install the `react-router-dom` npm module.
-
-```jsx
-import React from 'react'
-import {render} from 'react-dom'
-import {HashRouter as Router, Route} from 'react-router-dom'
-
-import Home from './components/Home'
-import About from './components/About'
-import Team from './components/Team'
-
-const App = (props) => {
- return (
-
-
-
-
-
-
-
- )
-}
-
-export default App
-```
-
-When the user visits any URL on your site, they'll end up looking at the `App` component and one of the route components inside of it depending on the URL.
-
-The URL will be a little strange looking! For example:
-
-```
-https://localhost:8080/#/?_k=b2xoft
-```
-
-This is _hash routing_. It's used to prevent browsers from firing off a request to the server every time a URL like `https://localhost:8080/routename` is visited.
-
-When we want to add a new route, we just add it inside the `Router` component:
-
-```jsx
-
-
-
-
-
-
-```
-
-Each time you add a new route, you'll need to `import` the component that it references. Visitors to `/#/users` will see the `Users` component and not `Home`.
-
-We can use `exact` when we want to specify a default route for our app. For example, we may wish to render a home page when a user first loads our app. This is not needed because the `Landing` component is the default child for our `App` component and therefore the path would be `/`:
-
-```jsx
-
-
-
-```
-
-
-### Linking to routes
-
-We can create links between our routes, but we don't do it using an anchor tag (``). Instead, React Router provides us with a `Link` component:
-
-```jsx
-// App.jsx
-import {Link} from 'react-router-dom'
-
-// ...
-
- render () {
- return (
-
- Welcome! Choose from the following pages:
-
-
All about wombats
-
All about aardvarks
-
All about jerboas
-
-
- )
- }
-```
-
-The `to` prop in each `Link` tells us which route it's going to.
-
-
-### Route parameters
-
-To specify a route parameter (a variable in the URL which will be available in the route's component), React Router uses a similar scheme to many other libraries: a colon followed by the variable name.
-
-```jsx
-
-
-
-
-
-
-
-```
-
- - The second route above will match `/wombats/123` and `/wombats/abc`. The `id` from the URL will be available in `props.match.params.id`.
- - The third route above will match `/aardvarks/123` and `/aardvarks/abc`. The `name` from the URL will be available in `props.match.params.name`.
-
-```jsx
-// Wombats.jsx
-render ({match}) {
- const {id} = match.params // using ES6 destructuring
- return (
-
You asked for the wombat with id {id}.
- )
-}
-```
-
-
-### Nesting routes
-
-Routes are nested in a hierarchy, just like the URL itself. Components have a one-to-one mapping with levels in a URL. So to nest routes (URLs), you do so my nesting components. Within the component you will add any routes that display components deeper in the hierarchy.
-
-```jsx
-// App.jsx
-
-
-
The UI for App goes here
-
-
-
-```
-
-```jsx
-// Kumquats.jsx
-
-
-
The UI for Kumquats goes here
-
-
-
-```
-
-To see the `Kumquats` component, which is wrapped in the `App` component, we would navigate to `/Kumquats/wombats`
-
-
-### Resources
-
-* https://reacttraining.com/react-router/web/guides/quick-start
-* https://egghead.io/courses/add-routing-to-react-apps-using-react-router-v4
diff --git a/react/state.md b/react/state.md
deleted file mode 100644
index 414b17a..0000000
--- a/react/state.md
+++ /dev/null
@@ -1,58 +0,0 @@
-React components use two different kinds of data: _state_ and _props_. State is data that undergoes change within a component, and props is data that is passed to a component for rendering, and should not change.
-
-One way to think of the difference is:
-- **State** is data **created within** a React Component and can be changed within a component using `this.setState()`
-- **Props** is data **passed into** a Component from its parent and should not be changed.
-
-One use of state is the data returned from API calls. In this example, the `` component consumes a web API to retrieve widgets.
-
-```js
-import React from 'react'
-
-import api from '../api'
-import WidgetList from './WidgetList'
-
-class App extends React.Component {
-
- constructor (props) {
- super(props)
- this.state = {
- widgets: []
- }
- this.renderWidgets = this.renderWidgets.bind(this)
- }
-
- componentDidMount () {
- api.getWidgets(this.renderWidgets)
- }
-
- renderWidgets (err, widgets) {
- this.setState({
- widgets: widgets
- })
- }
-
- render () {
- return (
-
-
Widgets FTW!
-
-
- )
- }
-}
-
-export default App
-```
-
-There are a number of things to notice about the sample above.
-
-* The component sets its initial state using the `constructor` method. This must be done so the component doesn't throw errors before the first `this.setState` call.
-
-* In the callback from the API call, `this.setState` is used to trigger a render. This is how React knows to call the render method again.
-
-* The state is being passed down to child components (`` in this case) as props. This is a common pattern. `` is responsible for rendering itself and its child components, but the child components only render using props.
-
-* The component waits until it has been mounted before calling the API. It does this by using the `componentDidMount` function, which is one of the lifetime methods.
-
-For more information about how to use state, see the [Interactivity and Dynamic UIs](https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html) article in the React documentation.
diff --git a/react/virtual-dom.md b/react/virtual-dom.md
deleted file mode 100644
index 3e65163..0000000
--- a/react/virtual-dom.md
+++ /dev/null
@@ -1,5 +0,0 @@
-The virtual DOM is a construct that sits outside of the browser's DOM, and it is able to output changes to the browser's DOM all at once. This minimizes the amount of work the browser must do, which makes changes a _lot_ faster. The real killer feature of the virtual DOM is its ability to compare changes before and after updates. This allows it to only make changes to the parts of the DOM that have changed instead of the whole thing.
-
-While React may have been the first to adopt the concept of a virtual DOM, it has since been adopted by the other frontend frameworks: Angular 2.0 and Ember (versions after 1.13). There are also a number of alternative implementations of virtual DOMs.
-
-React includes a new syntax for creating user interfaces that work with virtual DOMs called JSX. JSX is a syntax that combines JavaScript with a markup syntax that looks a lot like HTML. The use of JSX is not mandatory, but is the most common way of building React views. JSX was created from the recognition that views and the associated data have a one-to-one relationship that doesn't make sense to spread across multiple files.
diff --git a/redux/action-creators.md b/redux/action-creators.md
deleted file mode 100644
index 083ca00..0000000
--- a/redux/action-creators.md
+++ /dev/null
@@ -1,3 +0,0 @@
-Action creators are functions that return action objects. Even though actions are simple JavaScript objects, creating them with functions make them easier and more consistent to create and test.
-
-Given that actions are objects and reducers are pure functions (no side effects), action creators provide a place to perform async operations and call impure functions.
diff --git a/redux/async.md b/redux/async.md
deleted file mode 100644
index c1cd06a..0000000
--- a/redux/async.md
+++ /dev/null
@@ -1,43 +0,0 @@
-The [Redux docs](http://redux.js.org/docs/advanced/AsyncActions.html) provide an excellent introduction on how to write asynchronous operations in the context of Redux.
-
-We can dispatch async actions like this:
-
-```jsx
-import {connect} from 'react-redux'
-
-let ShowImages = ({dispatch}) => (
-
-)
-
-// Use react-redux to hook up the component to redux.
-// This will make `dispatch` available to the component as a prop.
-ShowImages = connect()(ShowImages)
-```
-
-Here `findImages` is just an action creator, but a slightly fancy one. Let's assume we're using [Superagent](https://github.com/visionmedia/superagent) to make the API call:
-
-```js
-function findImages (searchterm) {
- return (dispatch) => {
- dispatch(requestImages(searchterm))
-
- request
- .get(`https://api.instagram.com/v1/tags/search?q=${searchterm}`)
- .end((err, res) => {
- if (err) {
- return dispatch(retrievalError(err))
- }
- dispatch(receiveImages(searchterm, res.body)))
- })
- }
-}
-```
-
-Some key ideas from this:
-
-- We track progress of async calls using normal actions.
-- We can call dispatch more than once during the process.
- - For example, we could display a loading spinner when the `REQUEST_IMAGES` action is dispatched.
-- The function returned by the action creator is handled by thunk middleware (which takes care of providing the `dispatch` parameter, and `getState` is also available if required).
diff --git a/redux/connecting-to-react.md b/redux/connecting-to-react.md
index 98ff375..4681c7d 100644
--- a/redux/connecting-to-react.md
+++ b/redux/connecting-to-react.md
@@ -1,3 +1,5 @@
+# Connecting Redux to React
+
During React's unidirectional data flow, data is passed down through the component tree using _props_. Redux manages the application state that can be used as data for React. We are certainly capable to wire these libraries together using JavaScript, but the easiest way to combine them is to use the `react-redux` package.
At least two things need to happen to get these libraries working well together.
@@ -5,3 +7,4 @@ At least two things need to happen to get these libraries working well together.
1. React components need to be notified when to re-render a component tree. Normally we do this using the `setState()` method on React components. Since we'll be using Redux to manage the state, a perfect trigger is a store listener that's called on state changes.
2. New state and actions need to be applied to the component tree. React uses props for data when rendering components so it's reasonable to apply the Redux state to the React props.
+
diff --git a/redux/forms.md b/redux/forms.md
index 89b6d9e..415b555 100644
--- a/redux/forms.md
+++ b/redux/forms.md
@@ -1,3 +1,5 @@
+# Redux Forms
+
Sometimes forms in React can seem a bit clumsy, with lots of messing around in the component state. Several libraries have been developed which attempt to address the problem by keeping the form in the Redux store. [Redux Form](http://redux-form.com/6.5.0/) is perhaps the best-known of these. We're going to show you how to use [React Redux Form](https://github.com/davidkpiano/react-redux-form) (RRF) which in some ways is a little easier to get your head around!
@@ -211,3 +213,4 @@ const store = createStore(reducers)
```
Notice that in this example, `combineForms` takes the place of `combineReducers`. (You can actually use them together, but it's a bit more fiddly and you're probably better off using `createForms` for non-trivial cases.)
+
diff --git a/redux/fundamentals.md b/redux/fundamentals.md
deleted file mode 100644
index 58e7719..0000000
--- a/redux/fundamentals.md
+++ /dev/null
@@ -1,34 +0,0 @@
-Redux is a small library with a strong opinion about how UI views (components) should be managed. We could say, _Redux is nothing more than a state container_, but that's getting a little ahead of ourselves. That statement should make sense shortly.
-
-**A UI view is a function of state**. State is simply data; a JavaScript object in our case. To say that _y is a function of x_ just means that _y_ is the result of passing _x_ through a function. In Redux UI views — JSX components in our case — are the result of applying state, and reapplying the new state each time the state changes. This is consistent with what we've seen in both Handlebars templates and React.
-
-> Redux provides a consistent, beneficial way to manage the continually changing state being applied to our components.
-
-In order to reap the benefits of Redux we must implement a few concepts and follow some guidelines. These are the primary concepts in a Redux application:
-
-* A component or view is the visual part of our application. In React, these are written in JSX.
-* The _store_ is where **all** of the state of our application is stored and maintained.
-* _Actions_ are JavaScript objects that describe something that has happened in the application.
-* _Reducers_ are JavaScript functions that accept the current state and an action and return the new state.
-
-Here is a visual that provides a bit more detail:
-
-
-
-1. During initialisation the application will call Redux's `createStore()` method which tells Redux to create a store for the application. Redux only maintains a single store for an application.
-
- Once the store is created, the view subscribes to state changes by calling the store's `subscribe()` method and passing an event handler (callback) so it can respond to any state changes.
-
-2. While the application is being used, it will perform actions, which can come from user interaction or external events such as web API responses. When these things happen, our application will create create JavaScript objects that represent the action.
-
-3. The action object is sent to the store using the store's `dispatch()` method to let the store know something has happened.
-
-4. The store needs to know what impact this action has on the state. This is the job of the reducer. The store passes the current state and the action to the reducer: `reducer(state, action)`
-
-5. The reducer's only job is to return the new state. This should be a _pure function_, a function that has no side effects and only calls other pure functions. A pure function should always return exactly the same value when called with the same parameters. Pure functions also do not alter its arguments.
-
-6. When the reducer returns the new state to the store, the store updates the state and calls all subscribed listeners. When the event handler on the view (stateful component) is called by the store, it can call the store's `getState` method to get the changed state and then take the appropriate action.
-
-The previous steps describe the low-level events when an action results in updating the application's state. As we learn more about Redux and how to use it with React, we'll understand how many of these steps are hidden from us. Even though there will be less for us to do, it's important to understand what is being done for us. Hopefully this has provided a solid foundation.
-
-The earlier comment made about how _Redux is nothing more than a state container_ should make more sense now.
diff --git a/redux/reducer-composition.md b/redux/reducer-composition.md
deleted file mode 100644
index 60bb4b8..0000000
--- a/redux/reducer-composition.md
+++ /dev/null
@@ -1 +0,0 @@
-The reducer we send to Redux's `createStore()` method is a single function that returns the application's state object for any action that occurs within the application. That is a **lot** of responsibility for a single function. The way to keep the application maintainable is to split up the reducer into many smaller reducer functions that focus on a single part of the state. Reducer composition is about taking all of the small reducer functions and combine them into one function called the _root reducer_. Multiple reducer functions can be combined using Redux's `combineReducers()` function.
diff --git a/redux/relationship-to-react.md b/redux/relationship-to-react.md
deleted file mode 100644
index 4ce1cb7..0000000
--- a/redux/relationship-to-react.md
+++ /dev/null
@@ -1 +0,0 @@
-React is a library that applies a unidirectional data flow while rendering user interfaces based on changes in the virtual DOM. Redux is a library that manages application state and supports developer wellbeing by providing a consistent way to manage immutable state data. Neither of these libraries are dependent on each other, but they compliment each other wonderfully.
diff --git a/redux/state.md b/redux/state.md
deleted file mode 100644
index 2791c32..0000000
--- a/redux/state.md
+++ /dev/null
@@ -1,66 +0,0 @@
-In React there are two kinds of components: those that are aware of and respond to state changes, called stateful _containers_, and those that only render the data supplied to them, called stateless _components_. This does not change when using Redux — it actually makes it easier. Both of these things necessary to get these libraries working well together can be placed in a stateful component — the only kind that knows about Redux.
-
-
-### Making the store available
-
-Stateful components will exist inside of stateless components and visa versa for potentially many layers deep. We don't want to have to pass the Redux store through all of the layers — especially if they aren't going to use it. The `react-redux` package provides the `Provider` component that makes the store available to all containers regardless of their location in the hierarchy.
-
-```js
-import { Provider } from 'react-redux'
-let store = Redux.createStore(reducer)
-ReactDOM.render(
-
-
- ,
- document.getElementById('app')
-)
-```
-
-
-### State change notifications
-
-The first thing we listed above that needs to happen to use these libraries together is for React components to be re-rendered during Redux state changes. The `react-redux` package provides the `connect()` function for this very reason. In our stateful containers, we pass `connect` two functions we want to be called during state changes: `mapStateToProps` and `mapDispatchToProps`.
-
-```js
-const ListOfAllThings = connect(
- mapStateToProps,
- mapDispatchToProps
-)(ThingList)
-
-export default ListOfAllThings
-```
-
-In the function that `connect()` returns, we pass the stateless component we want the data applied to (`ThingList` in our example above). But where does its data (props) come from?
-
-
-### Mapping Redux state to React props
-
-The `mapStateToProps` function is called with the Redux state as a parameter and this function gives us the opportunity to map state into props the component (`ThingList` in our example) is expecting.
-
-```js
-const mapStateToProps = (state) => {
- return {
- things: state.things
- }
-}
-```
-
-In our example, `ThingList` is expecting a prop called `things` so we populate it with the array from the state being passed in.
-
-
-### Mapping bound Redux actions to React props
-
-The `mapDispatchToProps` works the same way `mapStateToProps` does. It is called each time the Redux store experiences a state change. It passes a `dispatch` function we can wrap and pass to our stateless components as props.
-
-```js
-import { showDetails } from '../actions'
-const mapDispatchToProps = (dispatch) => {
- return {
- showDetails: (id) => {
- dispatch(showDetails(id))
- }
- }
-}
-```
-
-Now when our `ThingList` component calls `this.props.showDetails` with an `id`, it will pass the `id` to our action creator and the action it returns will be dispatched to the Redux store.
diff --git a/rendering/client-side-rendering.md b/rendering/client-side-rendering.md
index 24a6502..d67011e 100644
--- a/rendering/client-side-rendering.md
+++ b/rendering/client-side-rendering.md
@@ -1,6 +1,9 @@
+# Client-side Rendering
+
The process of client-side rendering is exactly the same as what we experienced on the server. This process includes two components:
* A template is a file that contains the user interface (HTML) with placeholders and flow control statements (if statements and loops).
* A data object to replace the placeholders in the template.
The main difference between client-side and server-side rendering is how the templates are located. Sometimes the client will need to make an HTTP request to retrieve a template. In server-side rendering they can be easily found on the server.
+
diff --git a/rendering/testing-template-rendering.md b/rendering/testing-template-rendering.md
index d3b20e1..153c7db 100644
--- a/rendering/testing-template-rendering.md
+++ b/rendering/testing-template-rendering.md
@@ -1,3 +1,5 @@
+# Testing Client-side Template Rendering
+
Templates are often compiled before the data is applied. The compilation of a template usually results in a function that accepts a single input and returns HTML. This is great from a testing perspective because we can test the result given a known input. For client-side rendering, we can either perform this in the browser or directly in the terminal.
```js
@@ -14,3 +16,4 @@ test('test the greeting template', function (t) {
t.end()
})
```
+
diff --git a/server/express-router.md b/server/express-router.md
deleted file mode 100644
index 6a47ad2..0000000
--- a/server/express-router.md
+++ /dev/null
@@ -1,85 +0,0 @@
-Previously, we've learnt to declare our routes directly within our `server.js` file:
-
-```js
-/*
- * server.js
- */
-
-var express = require('express')
-
-var PORT = 3000
-var app = express()
-
-app.get('/', function (req, res) {
- res.send('
Hello world
')
-})
-
-app.listen(PORT, function () {
- console.log('The server is listening on port', PORT)
-})
-```
-
-However, as we add more routes to our Express server, this can become cumbersome. Express has built in functionality to separate our routes and make our code more modular:
-
-### Express Router
-
-We can use `express.Router` to create modular route handlers. The following example creates a router as a module, defines some routes, and mounts the router module on a path in the main app (`server.js`).
-
-Let's say we want to create a `/birds` route where we can:
-- view a list of birds via get `/birds`
-- view a single bird by id via get `/birds/:id`
-- add a new bird via post `/birds`
-
-Our code may look like this:
-
-```js
-/*
- * server.js
- */
-
-var express = require('express')
-var birds = require('./birds')
-
-var PORT = 3000
-var app = express()
-
-app.use('/birds', birds)
-
-app.listen(PORT, function () {
- console.log('The server is listening on port', PORT)
-})
-
-/*
- * birds.js
- */
-
-var express = require('express')
-var router = express.Router()
-
-router.get('/', function (req, res) {
- // ...
-})
-
-router.get('/:id', function (req, res) {
- // ...
-})
-
-router.post('/', function (req, res) {
- // ...
-})
-
-module.exports = router
-```
-
-Notice the differences:
-
-- `server.js`
- - We use `app.use` instead of `app.get` to add our routes to our server.
- - We put the name of the route `/birds` to specify that our `birds.js` will handle **ALL** routes that start with `/birds`.
-
-- `birds.js`
- - Notice how we don't specify `birds` anywhere in this file? This is because we have already specified this in our `server.js`! This means that even though our first route is to `/`, it is **actually** `/birds` because we have prefixed the route in our server file.
- - We require in `express` and define a separate `var router = express.Router()` as a separate variable.
- - We specify `router.get` and `router.post` for the individual routes and these take in **two** parameters - a path `/` and a `req, res` callback function.
- - We export the router, and not the individual functions.
-
diff --git a/server/express.md b/server/express.md
deleted file mode 100644
index 0a8c08d..0000000
--- a/server/express.md
+++ /dev/null
@@ -1,254 +0,0 @@
-Express is a minimalist web framework for Node.js. Express makes it easy to create server-side web applications by providing an easy way to read and manipulate the HTTP requests and responses.
-
-
-### Responding with a string
-
-Responding to a client request is often just a matter of using the `res` parameter. This is a Node.js response object that is provided through Express. The following is a simple web server that only responds with "Hello world" when a `GET` request is made to the root of the application. It listens for connections on port 3000.
-
-```js
-// server.js
-var express = require('express')
-
-var PORT = 3000
-var app = express()
-
-app.get('/', function (req, res) {
- res.send('
Hello world
')
-})
-
-app.listen(PORT, function () {
- console.log('The server is listening on port', PORT)
-})
-```
-
-To see this in action, start the server by running `node server` in your terminal, and visit http://localhost:3000 in your browser. You can also run `curl http://localhost:3000` in another terminal tab or window.
-
-The `app.get()` call allows us to define endpoints, also called routes, such as `/`. The server will only to respond to routes our application defines. Attempts to reach any other endpoint will cause Express to send a `404 File not found` response. If you start the server and run `curl http://localhost:3000/foo` in your terminal, you should see `Cannot GET /foo`.
-
-
-### Separation of concerns
-
-Because the routes are the only bit of code (so far) that isn't related to running the server, we should put them in their own file so we can test them.
-
-```js
-/*
- * server.js
- */
-
-var express = require('express')
-var routes = require('./routes')
-
-var PORT = 3000
-var app = express()
-
-app.get('/', routes.index)
-
-app.listen(PORT, function () {
- console.log('The server is listening on port', PORT)
-})
-
-/*
- * routes.js
- */
-
-module.exports = {
- index: index
-}
-
-function index (req, res) {
- res.send('
Hello world
')
-}
-
-/*
- * routes-tests.js
- */
-
-var test = require('tape')
-var routes = require('./routes')
-
-test('routes.index responds with Hello world', function (t) {
- var res = { send: send }
-
- routes.index(null, res)
-
- function send (msg) {
- t.equals(msg, '
Hello world
')
- t.end()
- }
-})
-```
-
-
-### Responding with a file
-
-Rather than responding to a request with an HTML string, we may have an HTML file prepared to send. We can easily send that file using the [`sendFile`](http://expressjs.com/en/api.html#res.sendFile) method.
-
-```js
-/*
- * server.js
- */
-
-...
-var routes = require('./routes')
-app.get('/home', routes.home)
-...
-
-/*
- * routes.js
- */
-
-module.exports = {
- home: home
-}
-
-function home (req, res) {
- res.sendFile(__dirname + '/index.html')
-}
-
-/*
- * routes-tests.js
- */
-
-var test = require('tape')
-var routes = require('./routes')
-
-test('routes.home responds with index.html', function (t) {
- var res = { sendFile: sendFile }
-
- routes.home(null, res)
-
- function sendFile (file) {
- t.equals(file, __dirname + '/index.html')
- t.end()
- }
-})
-```
-
-In the route, `__dirname` is a global Node.js object that refers to the name of the folder for the currently executing script.
-
-
-### Accepting query parameters
-
-One of the ways we can send data from the client to the server is to send name/value pairs in the URL, for example `http://localhost:3000?name=value`. Our application can retrieve these values from the `req.query` object. The following example sends a value it has received back in the response.
-
-```js
-/*
- * server.js
- */
-
-...
-var routes = require('./routes')
-app.get('/webapps', routes.webapps)
-...
-
-/*
- * routes.js
- */
-
-module.exports = {
- webapps: webapps
-}
-
-function webapps (req, res) {
- res.send(req.query.name + ' is building web apps')
-}
-
-/*
- * routes-tests.js
- */
-
-var test = require('tape')
-var routes = require('./routes')
-
-test('routes.webapps response includes a querystring parameter', function (t) {
- var res = { send: send }
- var req = { query: { name: 'Robin' } }
-
- routes.webapps(req, res)
-
- function send (msg) {
- t.equals(msg, 'Robin is building web apps')
- t.end()
- }
-})
-```
-
-You can see this route work by starting the server and running `curl http://localhost:3000/webapps?name=Robin` in your terminal.
-
-
-### Route parameters
-Another way we can send data to the server from the client is by using route parameters. For example on GitHub when you go to http://github.com/[org-name]/[repo-name] the GitHub server is looking at those parts of the URL to determine which data to show you.
-
-```js
-app.get('/:org/:repo', function (req, res) {
- res.send('Org: ' + req.params.org + ', Repo: ' + req.params.repo)
-})
-```
-
-
-### Saving data to server memory
-
-Express provides the object `app.locals` that we can use to store data on the server.
-
-```js
-/*
- * server.js
- */
-
-var express = require('express')
-var routes = require('./routes')
-var app = express()
-
-app.get('/add', routes.add)
-app.get('/answer', routes.answer)
-...
-
-/*
- * routes.js
- */
-
-module.exports = {
- add: add,
- answer: answer
-}
-
-function add (req, res) {
- req.app.locals.op1 = parseInt(req.query.op1, 10)
- req.app.locals.op2 = parseInt(req.query.op2, 10)
- res.send('Got it. Is this the answer?')
-}
-
-function answer (req, res) {
- var result = req.app.locals.op1 + req.app.locals.op2
- res.send('I hope you are expecting ' + result)
-}
-
-/*
- * routes-tests.js
- */
-
-var test = require('tape')
-var routes = require('./routes')
-
-test('routes.add saves numeric operands on the server', function (t) {
- var res = { send: function () {} }
- var req = {
- query: {
- op1: '11',
- op2: '22'
- },
- app: {
- locals: {}
- }
- }
-
- routes.add(req, res)
-
- t.equals(req.app.locals.op1, 11)
- t.equals(req.app.locals.op2, 22)
- t.end()
-})
-```
-
-Express is capable of much more than we're showing here, but this is enough to get us started. We'll continue to explore more of what Express has to offer, such as static files, view template rendering, and its middleware pipeline, in the near future.
-
diff --git a/server/node-debugging.md b/server/node-debugging.md
deleted file mode 100644
index 15672de..0000000
--- a/server/node-debugging.md
+++ /dev/null
@@ -1,114 +0,0 @@
-Node comes with a [built in debugger](https://nodejs.org/api/debugger.html) you can use to inspect what is going on in your code.
-
-You can use it by putting `debug` after your node command. For example, `node debug server.js`
-
-You are now in an interactive shell where you can type javascript. Try `1+1` or `console.log('hi')`.
-
-This shell will go through your JavaScript code one line at a time. Type `help` to see all the commands available.
-
-* `help` prints out the options.
-* `next` takes you to the next line of code.
-* `watch` prints the value of an expression every step forward. For example `watch('myVariable')`.
-* `unwatch` will stop watching a variable.
-* `cont` will stop going line by line and run until the next break point.
-* `setBreakpoint` puts a marker that tells the debugger to stop when it gets to that line `setBreakpoint(10)`
-* `clearBreakpoint` removes a breakpoint. For example `clearBreakpoint('file-name.js', 10)`.
-* `repl` launches a full JavaScript REPL where you can view any variables in your code.
-
-Another useful way to specify a breakpoint in your code is by putting `debugger` in your JavaScript.
-
-```js
-1: function createBoard(length) {
-2: const board = []
-3: debugger
-4: }
-```
-
-Now anytime the debugger gets to line 3 it will automatically stop.
-
-
-## Visual Studio Code
-
-[VS Code](https://code.visualstudio.com) is an open source editor using the same Electron technology as Atom. It provides a debugging client that works without having to use the browser tools.
-
-To get started, we recommend you open the debugging tools (the little bug with a line through it on the toolbar) and click the start button (green arrow). It will ask you to choose an option from a list: choose _Node 6.3+_ for the most up-to-date debugger. It will show you a `launch.json` file which you can leave mostly unchanged. However, you may want to add a `skipFiles` option to your config:
-
-```json
- "configurations": [
- {
- "name": "Launch Program",
- "type": "node2",
- "request": "launch",
- "program": "${workspaceRoot}/app.js",
- "cwd": "${workspaceRoot}",
- "skipFiles": [
- "node_modules/**/*.js"
- ]
- }
- ]
-```
-
-This will avoid having the debugger stop on files that aren't your code: files that belong to packages like Express or Knex, for example. You should also change the "program" property to point to your main source file, probably `index.js` or `server.js`.
-
-
-## Debugging in the browser and the `--inspect` flag
-
-Historically, one of the most popular debugging tools in Node development was [Node Inspector](https://github.com/node-inspector/node-inspector). More recent versions of Node support the `--inspect` flag, which allows the V8 Inspector to attach to a node process. This means that you can use the Chrome DevTools debugger without the need for Node Inspector (in fact, Node Inspector does not work with Node versions greater than 6.3, and the project appears to have been shelved or abandoned).
-
-Being able to step through your code in a terminal-type of environment is useful, but the debugging tools available inside of your browser are much more powerful. Using `--inspect` gives you the ability to use your browser's development tools to debug your server-side Node application. Think about that for a minute. Yes, this is very cool. To use `--inspect` in your project, add a script in your `package.json`:
-
-```js
-"scripts": {
- "debug": "node --debug-brk --inspect server.js"
-}
-```
-
-(The `--debug-brk` flag stops execution on the first line, and is optional.) This can be run in your terminal using `npm run debug`. You'll see a console notification that looks like this:
-
-```
-Debugger listening on port 9229.
-Warning: This is an experimental feature and could change at any time.
-To start debugging, open the following URL in Chrome:
- chrome-devtools://devtools/remote/serve_file/@60cd6e859b9f557d2312f5bf532f6aec5f284980/inspector.html?experiments=true&v8only=true&ws=localhost:9229/node
-```
-
-Copy/paste that URL into your browser to start debugging. (If you want the debugger to stop on the very first line of code, you can add the `--debug-brk` flag to your script.)
-
-`--inspect` isn't only useful for server-side web development. You can also use it for generic Node modules. However, if you are using it for server-side developement, you'll probably be interested in Nodemon too.
-
-
-## Nodemon
-
-Often when you're debugging, it's useful to be able to make changes and see the results of those changes. In these times, having to stop and restart the server becomes tedious pretty quickly. While Node Inspector's `--save-live-edit` might work for you, another option could be to have the server automatically restart whenever one of its files are changed. This is what Nodemon does.
-
-To use Nodemon, install it and use it like this:
-
-```sh
-npm install -g nodemon
-nodemon server
-```
-
-
-## Better together
-
-Nodemon and `--inspect` can also be used together. This allows you to debug using the rich developer tools in your browser and the application will restart each time you make a change. You can run the terminal commands above in two different terminal windows/tabs, but it is probably easier to create an npm script like this one:
-
-```js
-"scripts": {
- "debug": "nodemon --debug-brk --inspect server.js"
-}
-```
-
-With current versions of Node, the debugger URL will change each time the server is restarted. The pain of this can be alleviated somewhat with [NIM](https://chrome.google.com/webstore/detail/nim/gnhhdgbaldcilmgcpfddgdbkhjohddkj), a Chrome plugin which reloads the debugger each time the URL changes.
-
-Understanding how to debug your applications with tools more robust than `console.log` will put you in the driver seat to explore the entire runtime environment of your application. Be sure you use this capability to increase your understanding.
-
-
-## Node Monkey
-
-Another debugging tool worth checking out is [Node Monkey](https://github.com/jwarkentin/node-monkey), which provides a way to show server output in the browser console, as well as issue debugging commands to your running program.
-
-
-## Challenge
-
-Try to complete today's exercise without writing a single `console.log` for debugging!
diff --git a/server/node-npm.md b/server/node-npm.md
deleted file mode 100644
index fae2454..0000000
--- a/server/node-npm.md
+++ /dev/null
@@ -1,18 +0,0 @@
-**Node.js** is a _server-side_ JavaScript environment that also lets you run JavaScript in the terminal, which is pretty exciting! So far in your projects you have mainly been using JavaScript on the _client-side_ (in the browser.)
-
-**NPM** is a package manager which lets you use other people's JavaScript modules. We don't want to write everything from scratch or we'll be here forever! One of the wonderful things with open source programming is the ability to use and publish code to help achieve certain things. By using modules and libraries we can get to doing the fun stuff faster.
-
-We'll cover this in a lot more detail later this week. Suffice to say it's very exciting and incredibly powerful.
-
-
-
-Make sure you're using an up to date version of Node (6.x) and NPM (v3.x):
-
-```
-which node
-node -v
-npm -v
-```
-
-Use NVM to keep your Node.js and NPM up to date.
-
diff --git a/server/npm.md b/server/npm.md
deleted file mode 100644
index 883298f..0000000
--- a/server/npm.md
+++ /dev/null
@@ -1,20 +0,0 @@
-CommonJS is a specification which allows you to _require_ other JavaScript files: to pull them into your code and use their contents. Node follows this specification.
-
-npm is a package manager. [npmjs.com](https://www.npmjs.com) hosts packages which we can install, then require in.
-
-npm reads the `package.json` file in the root directory of your project. It contains one JSON object which is used to provide configuration. Of particular interest are the `scripts` and `dependencies` properties.
-
-Useful npm commands to understand:
-
- - `npm install` - installs all the dependencies listed in your `package.json` file in a `node_modules` folder
- - [`npm start`](https://docs.npmjs.com/cli/start) - usually used to launch a server or other continuous development/debugging environment
- - [`npm test`](https://docs.npmjs.com/cli/test) - usually used to launch your test suite
- - `npm run foo` - looks for a script in your `package.json` called 'foo' (in this example) and runs it
-
-Notes:
-
- - If you want to reinstall your `node_modules`, you can first delete them away with `rm -rf node_modules`.
- - Prevent your `node_modules` folder from being committed by adding it to your `.gitignore` file.
- - To learn more about the `.gitignore` file, read [the docs](https://git-scm.com/docs/gitignore)
- - See how another project has used its `.gitignore` file: https://github.com/ssbc/patchwork
-
diff --git a/server/passing-id-to-get-routes.md b/server/passing-id-to-get-routes.md
deleted file mode 100644
index f4f402c..0000000
--- a/server/passing-id-to-get-routes.md
+++ /dev/null
@@ -1,49 +0,0 @@
-When rendering on the server, we often redirect to another route when submitting a form. When we update an existing entity, we need to provide an `id` to the route so we can tell the database which entity to modify.
-
-Say you have a `POST` `/cats/:id` route to update cats. (Note: this would ideally be a `PUT`, but browsers can't reliably use it.) To update the cat with ID 3, we would visit `/cats/3/edit`. On this page would be a form that looks like:
-{% raw %}
-```xml
-
-```
-{% endraw %}
-Notice we're setting the form to post to {% raw %}`/cats/{{cat.id}}`{% endraw %} which would be rendered to `/cats/3` in our case.
-
-On the server our routes would look something like:
-
-```js
-app.get('/cats/:id/edit', routes.edit)
-app.post('/cats', routes.create)
-app.post('/cats/:id', routes.update)
-```
-
-The update route will be able to access the id of the cat we're updating by looking in `req.params`. Specifically for a form posted to `/cats/3`, `req.params` will equal:
-
-```js
-{
- id: '3'
-}
-```
-
-(notice that 3 is a string not a number)
-
-Here's a more complete example:
-
-```js
-function update (req, res) {
- var id = Number(req.params.id)
- var name = req.body.name
-
- data.updateCat({
- name: name
- })
- .then(function () {
- return res.redirect('/cats/' + id)
- })
- .catch(function (err) {
- return res.send(500, err)
- })
-}
-```
diff --git a/server/redirect-from-post-routes.md b/server/redirect-from-post-routes.md
deleted file mode 100644
index b0d6b80..0000000
--- a/server/redirect-from-post-routes.md
+++ /dev/null
@@ -1,11 +0,0 @@
-When doing server-side rendering, it's common to have a route that shows a form to either add or edit some data. These forms POST to a different route that saves the data posted from the form. For example, you might have a GET `/add` route that shows a form and and a POST `/create` route that saves the data.
-
-```js
-app.get('/cats/new', routes.new)
-app.post('/cats', routes.create)
-```
-
-Inside `routes.new` you will likely `res.render()` the form, but in `routes.create` you should NOT `res.render()` because it leads to a poor user experience and fragments your views. This is because if the user refreshes the resulting page, their browser will prompt them to resubmit the form data, which could be confusing.
-
-Also, think about what page you would render from `POST`ing to `/cats`. If you're adding something, you're probably adding to a list of things. You probably already have an exiting route that shows this list (`GET` `/cats`). Having two different routes that show the same page gets confusing, and dangerous. It's much better in this case to `res.redirect()` to the list route you already have.
-
diff --git a/server/static-files.md b/server/static-files.md
deleted file mode 100644
index 6d21a3e..0000000
--- a/server/static-files.md
+++ /dev/null
@@ -1,18 +0,0 @@
-Static files are files that are not dynamic and aren't rendered with a template engine. These are files that should be served as-is, without modification. Some examples of static files are HTML, CSS, and JavaScript files that should be sent directly to the browser. Images such as JPGs and PNGs are also static.
-
-It would be really unfortunate if we had to define a route and use `res.sendFile` for every static file in our application. Express.js makes this really easy by giving us a way to define a folder in which to put all of our static files.
-
-```js
-var express = require('express')
-var app = express()
-app.use(express.static('public'));
-```
-
-Now we can place a directory structure under a `public` folder for each type of static file we need to serve. This could create paths on our web application like:
-
-* http://localhost:3000/images/logo.png
-* http://localhost:3000/styles/main.css
-* http://localhost:3000/scripts/tiles.js
-
-Notice how `public` is **not** part of the URL even though the `images`, `styles` and `scripts` folders are inside `public`. To reference these files from your HTML files, you can use an absolute path, `/images/logo.png`. (A leading `/` means the 'root' path or base directory.)
-
diff --git a/server/templates.md b/server/templates.md
deleted file mode 100644
index 12f23b9..0000000
--- a/server/templates.md
+++ /dev/null
@@ -1,89 +0,0 @@
-Templates are combined with data, during a process called view _rendering_. This is done by a _template engine_ and there are a number of different template engines for every web framework (including Express.js). Each template engine has an associated template language that's used inside the view language, in our case HTML. The template language defines how to create placeholders that it can later replace with data during rendering. If a paint-by-numbers kit is metaphor for templates and data, rendering is painting and the template engine is the painter.
-
-[Handlebars](http://handlebarsjs.com) is a popular templating library which evolved from another library called [Mustache](https://mustache.github.io). Both of these libraries boast being _logic-less_, meaning the template language doesn't encourage complex logic in the views. They do contain rudimentary conditionals and iterators, but lack a lot of features compared to other templating options. Other templating libraries offer a lot of language features and some provide the full capabilities of the JavaScript language. The authors of Handlebars/Mustache and many other developers consider the logic-less decision a feature. Their premise is the view should not contain complex logic and its data should be specific to the template. EDA tends to agree, so we'll use Handlebars. We choose Handlebars over Mustache because it has some nice composition features.
-
-The placeholder syntax in Handlebars (and Mustache) looks like, well, mustaches! Each placeholder name is surrounded by {% raw %} `{{ }}` {% endraw %} (double curly braces).
-
-{% raw %}
-```xml
-
-
{{para}}
-```
-{% endraw %}
-
-```js
-var data = {
- para: "Hi, I'm a paragraph."
-}
-```
-
-In this example, `para` refers to a property on the `data` object used as the data applied by the template engine. The view that results from the rendering will be:
-
-```xml
-
Hi, I'm a paragraph.
-```
-
-
-### Layouts and partials
-
-{% raw %}
-
-One of the great things about using a templating engine is the ability to remove most of the HTML duplication from your web app. Layouts and partials are the feature that helps you do this. Layouts represent the structural part of each page. For example, if each of your pages had a header, a footer and navigation down the left side, you can define this structure in a layout file. Of course the main part of the page will depend on the route the user is navigating to. And this dynamic page needs to exist within the layout. Use `{{{body}}}` (that's right, 3 curly braces wrapping the word `body`) to specify where the rest of the page will go. Here is an example:
-
-```xml
-
- ...
-
...
-
- {{{body}}}
-
-
-
-```
-{% endraw %}
-
-If you have some HTML that is repeated multiple times on a single page or throughout the app, the HTML can be placed within a partial and applied wherever it's needed. Using partials, you only need to make a change once, in the partial, and the change will take effect everywhere the partial is used. For example of how partials are used, consider this scenario. If you're showing a contact card for each user, you can define the markup of the contact card in a separate file and include it when you need it.
-
-{% raw %}
-```xml
-
-
-
-
{{name}}
-
-
-
-{{#each contacts}}
- {{> contact-card}}
-{{/each}}
-```
-{% endraw %}
-
-Partials are referenced based on their filename (without the file extension) and can be referenced from page templates, layouts or even other partials; pretty much from anywhere.
-
-
-### Rendering with Express.js
-
-Because integration with Express.js requires middleware, we'll use the `express-handlebars` npm package instead of the generic Handlebars package. In the following example, assume our data is coming from a module defined in `data.js`. It's `home` property contains an object for the `home` template.
-
-```js
-var express = require('express')
-var hbs = require('express-handlebars')
-
-var data = require('./data')
-
-var app = express()
-
-app.engine('hbs', hbs(
- extname: 'hbs',
- defaultLayout: 'main'
-))
-app.set('view engine', 'hbs')
-
-app.get('/', function (req, res) {
- res.render('home', data.home)
-})
-```
-
-Notice how this uses `res.render` in our route to tell Express to use the Handlebars engine we registered for `*.handlebars` template files. We also told Express that our views are located in the `views` folder. Therefore, our `/` route is applying `data.home` to the template located at `views/home.handlebars`.
-
diff --git a/server/user-data.md b/server/user-data.md
deleted file mode 100644
index 7774e8c..0000000
--- a/server/user-data.md
+++ /dev/null
@@ -1,76 +0,0 @@
-When our users request a page in our app, their browser issues an HTTP GET request. When they submit a form in our app, the form's `method` attribute, which is the HTTP method/verb our form should use, determines how their browser will send the form data to our server-side code. We can use the `get` method like this:
-
-```xml
-
-```
-
-And it will create this HTTP request:
-
-```
-GET /greetings?say=Hi&to=Mom HTTP/1.1
-Host: foo.com
-```
-
-Notice how the form fields are appended to the URL as query parameters.
-
-We can also use the `post` method like this:
-
-```xml
-
-```
-
-And it will create this HTTP request:
-
-```
-POST /greetings HTTP/1.1
-Host: foo.com
-Content-Type: application/x-www-form-urlencoded
-Content-Length: 13
-
-say=Hi&to=Mom
-```
-
-Notice how the form fields are sent in the body of the request.
-
-> The `method` our forms use impact on how we extract the form fields from the request on the server-side.
-
-If we use `get`, we can extract the values using `req.query` like this:
-
-```js
-...
-router.get('/greetings', function (req, res) {
- var greeting = req.query.say
- var recipient = req.query.to
- ...
-})
-...
-```
-
-If we use `post`, we must parse the body of the request. To do this, we need an additional module:
-
-```js
-var express = require('express')
-var bodyParser = require('body-parser')
-
-var app = express()
-app.use(bodyParser.urlencoded())
-
-...
-
-router.post('/greetings', function (req, res) {
- var greeting = req.body.say
- var recipient = req.body.to
- ...
-})
-...
-```
-
-The `body-parser` module is Node.js middleware that parses the body of requests and places the parameters as properties on `req.body`.
diff --git a/server/views.md b/server/views.md
deleted file mode 100644
index fca66f9..0000000
--- a/server/views.md
+++ /dev/null
@@ -1,9 +0,0 @@
-A *view* is the part of the web application that creates what the user sees in their browser. For a static website, such as the blogs you created in Phase 0, the view will be a single HTML file. In these cases, the HTML markup and the data are combined into a single file: the HTML file. However, in most web applications, the data is stored separately from the HTML and constructed dynamically when the user requests that page.
-
-Think about this in the context of Facebook. Facebook has millions of users, all of whom have a homepage that is unique to them. It would be impossible to write all of these pages as static HTML files. Instead, the page is constructed from templates. These are filed in by information that is fetched from a database and dynamically placed into the template (rendered) which creates a unique page for each user.
-
-Separating the data from how that data is displayed gives us a lot of flexibility and makes it easier to create pages that are specific to user or situation. Rather than include the data in each page, we add placeholders where we can add the data later. A _template_ for the web is an HTML page that contains placeholders for data instead of the actual data.
-
-A real-world example of a template is a paint-by-numbers kit. The paper with lines and numbers (an empty picture) is the template and the paint is the data. Multiple copies of empty pictures will have very different outcomes with different combinations of paint.
-
-
diff --git a/single-page-apps/bundling.md b/single-page-apps/bundling.md
index 924be3f..8e99f83 100644
--- a/single-page-apps/bundling.md
+++ b/single-page-apps/bundling.md
@@ -1,14 +1,12 @@
+# Bundling
+
The CommonJS pattern that Node uses (which allows us to _require_ modules, or code we've written in other files) is super powerful, but current web browsers don't support it.
One solution is to parse all the require statements and pull the code from each one into a single file. This is called _bundling_, and makes one massive file which the browser can read. (Bundling is also really common with CSS).
Thus, you write all your code in nice, modular files; importing functions and modules from node_modules. Then, before you serve your app, you 'bundle' it - this process takes all the code from your files and squishes it into one, long file which a web browser can read.
-There are several different bundling tools. We will be using Browserify (incidentally written by the author of Tape!)
+There are several different bundling tools. One of those is Browserify, incidentally written by the author of Tape.

-
-
-
-
diff --git a/single-page-apps/rendering-intro.md b/single-page-apps/rendering-intro.md
deleted file mode 100644
index debd6df..0000000
--- a/single-page-apps/rendering-intro.md
+++ /dev/null
@@ -1,2 +0,0 @@
-This is powerful, because if you render client-side, you don't have to wait for the server to render up an html page (and you don't have to wait for it to render some other peoples), AND you don't have to transport a bulky html page.
-We're moving into the neighbourhood where it's possible to just shoot JSON from client to server and back, and load all the page-weaving needed into our client's page.
diff --git a/testing/continuous-integration.md b/testing/continuous-integration.md
index 5c88206..a4b9b6d 100644
--- a/testing/continuous-integration.md
+++ b/testing/continuous-integration.md
@@ -1,9 +1,11 @@
-CI is a dev pattern that recommends continuously merging (inegrating) work as you go.
-Adding small pieces often, and running tests as you go means you know early when there are problems, and can adapt code.
-The inverse would be to build a monolithic feature, then try to merge it in an hope for the best.
+# Continuous Integration (CI)
+
+CI is an activity that is continuously integrating work as you go. Adding small pieces often, and running tests as you go means you know early when there are problems, and can resolve it shortly after you encounter them. The inverse would be to build a monolithic feature, then try to integrate it in an hope for the best.
There are many services that support CI, and do fancy things like auto-run all your tests every time you open a pull request.
-examples :
- - Travis CI
- - Jenkins
\ No newline at end of file
+Examples :
+- Travis CI
+- Circle CI
+- Jenkins
+
diff --git a/testing/cucumber-tests.md b/testing/cucumber-tests.md
index 7e16d6c..e65f305 100644
--- a/testing/cucumber-tests.md
+++ b/testing/cucumber-tests.md
@@ -1,3 +1,5 @@
+# Cucumber Tests
+
Cucumber is a flavour of integration tests that aim to improve collaboration between technical and non-technical people in developing software.
Tests are written in [Gherkin syntax](https://cucumber.io/docs/reference) which means that:
@@ -7,9 +9,9 @@ Tests are written in [Gherkin syntax](https://cucumber.io/docs/reference) which
* tests can be linked directly to the the team and client's broader intentions for the software such as User Stories or [Jobs-to-be-done](https://blog.intercom.io/using-job-stories-design-features-ui-ux/)
-## Cucumber in a BDD cycle
+## Cucumber in a Behaviour-driven Development (BDD) cycle
-A Behaviour Driven Development cycle that uses Cucumber might follow the following steps.
+A Behaviour-driven Development cycle that uses Cucumber might follow the following steps.
### 1. Intention clarification (user stories / jobs to be done)
@@ -22,7 +24,6 @@ For example, for a weather app we may define a User Story as the following:
As a User,
I want to view the likelihood of rain for my GPS coordinates
So that, when I go outside I know whether or not I need to take my jacket
-
```
We could re-write the same intention as a Job Story like so:
@@ -35,6 +36,7 @@ So I know whether or not to take my jacket
Most people use user stories, but either is fine.
+
### 2. Gherkin feature specification
Once we have clarified the intentions we can begin "speccing out" how users will flow through the app and how particular software features will meet the user's needs.
@@ -83,10 +85,12 @@ Note: to get this code to work we're spoofing the browser location `browser.loca
In the later steps we will write code to automate a browser that interacts with our software in the specific way detailed in the specification.
+
### 3. App scaffolding
The team can begin scaffolding the app, setting up the directory, the testing, build and deployment script etc. We'll need a basic server for our automated browser to interact with.
+
### 4. Cucumber automation
At the moment we have some text in a `/features/rain-likelihood.feature` file and you might be wondering how we will program a browser to run the test. This is the magic of cucumber. Cucumber interfaces between readable gherkin specs and less readable browser automation code. We still need to write this code and the following gives an example of the automation code written with [WebDriver](http://webdriver.io/) that drives the feature spec above.
@@ -130,14 +134,17 @@ A good thing about cucumber steps is that many of them will be reusable in other
The above example code is specific to the Webdriver API and could be written with a different browser automation library.
+
### 5. Development
We can now start developing our features. With the features spec'd out, developers can estimate their relative complexity. The Client or the Product Owner can prioritise the features they would like developed. As development progresses, a set of passing cucumber specs provide living documentation about what the software can and cannot do.
+
### 6. User acceptance tests
When a feature is complete and its cucumber tests pass, the development team can deploy the latest version of the app to a staging server. This allows the client to see a live version of the app and provide feedback and clarifications before features go live on production and the development team to conduct user testing. Near the end of the release cycle the team and the client may sit down and work through the new features on the staging app and their specs before the features are formally accepted.
+
## Further information
This document references the following concepts and tools:
@@ -148,10 +155,11 @@ This document references the following concepts and tools:
* [User Sories](../agile/user-stories.md)
* [Job Stories](https://jtbd.info/replacing-the-user-story-with-the-job-story-af7cdee10c27#.g9p9ceubs)
* [User Acceptance tests](http://www.tutorialspoint.com/software_testing_dictionary/use_acceptance_testing.htm)
-
-
+
+
Tools:
-
+
* [Gherkin syntax](https://github.com/cucumber/cucumber/wiki/Gherkin)
* [Webdriver](http://webdriver.io/)
* [Selenium](http://www.seleniumhq.org/)
+
diff --git a/testing/database.md b/testing/database.md
index 97c8e7c..5921c1b 100644
--- a/testing/database.md
+++ b/testing/database.md
@@ -1,3 +1,5 @@
+# Database Testing
+
We can write tests for code that touches a database in a similar way to testing for any other asynchronous function, but there is some infrastructure that makes writing such tests a little easier.
@@ -15,15 +17,15 @@ Another trick: ideally, we want our test database to be an _in-memory_ database.
We can create such a creature using SQLite3, by adding a `test` property to our `knexfile.js`:
```js
- test: {
- client: 'sqlite3',
- connection: {
- filename: ':memory:'
- },
- seeds: {
- filename: './tests/helper/seeds'
- }
+test: {
+ client: 'sqlite3',
+ connection: {
+ filename: ':memory:'
+ },
+ seeds: {
+ filename: './tests/helper/seeds'
}
+}
```
The `seeds` property might be new to you: the ordinary seeds will still run when we execute `npm run knex seed:run`. However, when we're using the `test` config the specified directory above will be used instead. This lets us isolate our seeds and provide very specific values just for the tests.
diff --git a/testing/enzyme.md b/testing/enzyme.md
deleted file mode 100644
index 32068cf..0000000
--- a/testing/enzyme.md
+++ /dev/null
@@ -1,134 +0,0 @@
-So, now we have components. How do we test them?
-
-User interface or view layer testing is a less well-defined area than unit testing. UI tests are typically thought of as _integration_ tests: they involve an interaction between the component you're testing and various other systems, like the DOM or React itself. It might seem like we're just testing one function, but in reality we're checking to see whether that function produces the correct result when integrated with other moving parts of the app.
-
-Some people think of UI testing as distinct from integration testing. We'll just call it integration testing for the sake of consistency with other parts of the curriculum. During your career in development, you'll discover that people have very strong opinions about testing!
-
-
-### Enzyme
-
-React has its own testing library, [react-addons-test-utils](https://facebook.github.io/react/docs/test-utils.html), but AirBnB created [Enzyme](https://facebook.github.io/react/docs/test-utils.html), a popular alternative which is widely used (even FaceBook links to it at the top of their own testing page). Enzyme's render methods all return a _wrapper_: an object with a variety of useful functions we can use to make assertions on the rendered components that come back to us.
-
-> Note: [enzyme-examples](https://github.com/dev-academy-challenges/enzyme-examples) has all the tests below included and set up with Webpack. You may find it helpful to clone down and run the tests while you experiment with Enzyme.
-
-Enzyme allows us to render our components in one of three ways, so we can check that what comes back is what we expect.
-
-
-#### Shallow
-
-The simplest method is shallow rendering. As its name suggests, this renders only one 'layer' in isolation, without rendering any other child components. This is one of the most common approaches. It reassures us that the behaviour we're testing isn't actually caused by another child component further down the tree.
-
-```js
-import test from 'tape'
-import React from 'react'
-import { shallow } from 'enzyme'
-
-import App from '../client/components/App'
-
-test('', t => {
- // Arrange
- const expected = 'React development has begun!'
-
- // Act
- const wrapper = shallow()
- const actual = wrapper.text()
-
- // Assert
- t.equal(actual, expected)
- t.end()
-})
-```
-
-A few things to notice here:
- - Even though we don't excplicitly refer to the `React` object, we need to import it in order for the test to work. This is because enzyme expects `React` to be defined, and we're using JSX.
- - The `wrapper` object is returned from a call to `shallow`. This is our rendering operation.
- - We use the `text()` method to get the contents of the rendered component as a string.
- - This test would only work on a very simple app, the starting one in the boilerplate that renders a string to the browser.
-
-How about something a bit more complex? Say we have a `List` component which must create one list item for each array element in the `things` prop. This is a nice, predictable behaviour that makes for a good test:
-
-```js
-test(' creates one item for each wombat', t => {
- // Arrange
- const wombats = ['herschel', 'gertrude', 'jemima']
- const expected = 3
-
- // Act
- const wrapper = shallow()
- const actual = wrapper.find('li').length
-
- // Assert
- t.equal(actual, expected)
- t.end()
-})
-```
-
-
-### Mount
-
-We use the mount rendering type when we have to test things that rely on the component being mounted as if it would be in a real browser. This lets us test component lifecycle methods (`componentDidMount`, `componentWillUpdate`, etc.) Mount is useful, but more expensive to run: it uses what's called a 'headless' browser, a browser we don't see but which runs in the test code so that the component can be rendered properly in the DOM. We should try to do most of our tests using `shallow`, as it is likely to be faster and nicely isolates the component we want to test.
-
-To check on the lifecycle methods, we can use [Sinon](http://sinonjs.org/). Sinon provides a way of _spying_ on a function! A spy in code is something that can tell us when a function call has taken place. Here's an example checking on a custom function we pass to a component that should be called when one of the `
` elements in `` is clicked:
-
-```js
-test(' calls moreWombatInfo when item clicked', t => {
- // Arrange
- const spy = sinon.spy()
- const wombats = ['herschel']
- const expected = 1
-
- // Act
- const wrapper = mount()
- const li = wrapper.find('li').first()
- li.simulate('click')
- const actual = spy.callCount
-
- // Assert
- t.equal(actual, expected)
- t.end()
-})
-```
-
-To get this to work, there are a number of browsers we could test with. The [example repo](https://github.com/dev-academy-challenges/enzyme-examples) uses [tape-run](https://www.npmjs.com/package/tape-run), which makes use of the same [electron](http://electron.atom.io/) technology that Slack is built with. You can also have tape-run use Chrome or other installed browsers to test against.
-
-There is a bit of extra setup required compared to an ordinary unit test: have a look at [test.config.js](https://github.com/dev-academy-challenges/enzyme-examples/blob/master/test.config.js), [index.loader.js](https://github.com/dev-academy-challenges/enzyme-examples/blob/master/test/index.loader.js) and the scripts section of [package.json](https://github.com/dev-academy-challenges/enzyme-examples/blob/master/package.json) to see if you can figure out what's going on. You don't absolutely have to understand every line here in order to start working with the tests!
-
-
-### Render
-
-The final Enzyme method does a 'static render': it doesn't use the lifecycle or other methods, but unlike shallow rendering, it _does_ render child components. It also uses [Cheerio](https://github.com/cheeriojs/cheerio) to parse the results of the render, which you might remember from earlier adventures in testing. This means you can use any selector that Cheerio provides.
-
-Say, for example, our `` component needs to include a `` child component. We can test for this like so:
-
-```js
-test(' includes a component', t => {
- // Arrange
- const wombats = ['herschel']
- const expected = true
-
- // Act
- const wrapper = render()
- const actual = wrapper.find('div.notes').length > 0
-
- // Assert
- t.equal(actual, expected)
- t.end()
-})
-```
-
-Notice that if you change `render` to `shallow`, the test will fail because shallow only renders the component you pass to it, not its children.
-
-
-### Avoid 'brittle' tests
-
-It's very easy to take this kind of testing too far. We should test parts of the view that we know are essential to its correct operation. We should try to avoid testing minor details of view and layout that might change frequently. For example, if our test depends on there being a full-stop at the end of the page title and a designer later decides to take it out, our test will break for no good reason! This creates more work for the developer, and doesn't add much value.
-
-
-### How many?
-
-Different projects will have different needs, but as a general rule we should probably write:
-
- - lots of unit tests
- - some integration tests that cover our API and/or database code
- - a smaller number of integration tests that cover our UI, focusing on key components
-
diff --git a/testing/integration-testing.md b/testing/integration-testing-1.md
similarity index 97%
rename from testing/integration-testing.md
rename to testing/integration-testing-1.md
index 845f630..d97a0e3 100644
--- a/testing/integration-testing.md
+++ b/testing/integration-testing-1.md
@@ -1,3 +1,5 @@
+# Integration Testing
+
[Integration testing](https://en.wikipedia.org/wiki/Integration_testing) is the process of testing how all your different modules are working in concert.
Client-side integration testing involves automating a browser and instructing it to visit specific pages, fill in fields and click on buttons in specified steps.
@@ -10,3 +12,4 @@ JavaScript packages which you can use to write tests which drive Selenium includ
- [Chimp](https://chimp.readme.io/)
These can take a bit of configuring, so it's worth shopping around and seeing what the best practice is before choosing a technology (this can change from year to year).
+
diff --git a/testing/integration.md b/testing/integration-testing-2.md
similarity index 99%
rename from testing/integration.md
rename to testing/integration-testing-2.md
index b380d4d..01fe91d 100644
--- a/testing/integration.md
+++ b/testing/integration-testing-2.md
@@ -1,3 +1,5 @@
+# Integration Testing
+
Automated integration testing treats the application like a black box and tests the graphical user interface (GUI) directly to assert it is displaying and behaving exactly like it should for a user. To do this, it launches a browser, navigates to the application, and interacts with the user interface (UI) the same way a user would. However, it does this automatically according to the instructions we give it - hands free!
This type of testing is very different from unit testing. Unlike unit testing, integration testing determines how well all parts of an application are working together instead of directly testing small units of code.
diff --git a/testing/post-routes.md b/testing/post-routes.md
deleted file mode 100644
index 411e1f2..0000000
--- a/testing/post-routes.md
+++ /dev/null
@@ -1,95 +0,0 @@
-We can send 'fake' data to our POST routes to check that the response is what we expect.
-
-We _could_ do this manually, by entering data into a form on a browser. However, we don't need to do this and it's probably better not to. We want to test in a way that's _automated_ and _repeatable_. We'll use [Supertest](https://github.com/visionmedia/supertest) to do our POST route testing.
-
-> Strictly speaking, this kind of test is not a _unit test_: we are testing our server, starting from the point where it receives a request to the moment it sends a response back to the client. Some tests involve more than one 'unit' of code, and they often follow the same path as a user making a request from the browser... we're just skipping the browser part!
-
-
-### Example: checking for confirmation
-
-Say we have a route that renders a Handlebars template and returns HTML confirming the form submission. We could test this like so:
-
-```js
-var test = require('tape')
-var request = require('supertest')
-var cheerio = require('cheerio')
-
-test("POST '/' returns confirmation including name", function (t) {
- // Arrange
- var formData = {
- name: 'flargle',
- address: '1 Flargle Lane'
- }
- var expected = 'Your submission was accepted, ' + formData.name
-
- // Act
- request(app)
- .post('/')
- .type('form')
- .send(formData)
- .end(function (err, res) {
- var $ = cheerio.load(res.text)
- var actual = $('body').html()
-
- // Assert
- t.error(err)
- t.ok(actual.includes(expected))
- t.end()
- })
-})
-```
-
-There's quite a bit going on in this example! Let's break down some of the major points to note:
-
- - We use `request.post` to specify the route we wish to test
- - We use `request.type` to specify that the data we're sending is a form
- - We use `request.send` to send the data, which Supertest will automatically convert to form fields
- - We only do our _assertions_ in the callback (the function passed to `request.end`. This is a test for _asynchronous_ code, so we need to wait for it to call the callback before we check any values.
-
-We use [cheerio](https://github.com/cheeriojs/cheerio) because the route is sending back HTML, and cheerio makes it easier to find the values we're looking for. Obviously, this wouldn't work so well if the route sent us a JSON or plain text response.
-
-Notice also that we're using the JavaScript string prototype function `.includes`, which returns a boolean. This is because the template often will contain extraneous characters like newlines and white space, which we're not really interested in but might make our test fail. For example:
-
-```shell
- ✖ should be equal
- ------------------
- operator: equal
- expected: 'Your submission was accepted, flargle'
- actual: '\n Your submission was accepted, flargle\n '
-```
-
-The route is obviously doing what it's told, but strictly speaking the text is different so the test will not pass. We could also `.trim` the string.
-
-
-### Example: server-side validation
-
-Sometimes users don't submit all the information they're supposed to! Maybe even most of the time. We shouldn't trust that all data we expect is actually being sent to our route. Try this on for size:
-
-```js
-test("POST '/' returns an error when name is missing", function (t) {
- // Arrange
- var formData = {
- address: '1 Flargle Lane'
- }
- var expected = 'Error'
-
- // Act
- request(app)
- .post('/')
- .type('form')
- .send(formData)
- .end(function (err, res) {
- var $ = cheerio.load(res.text)
- var actual = $('body').html()
-
- // Assert
- t.error(err)
- t.ok(actual.includes(expected))
- t.end()
- })
-})
-```
-
-This test looks for the word 'Error' in the HTML body as an indication that the route has returned with a notice letting the user know they didn't provide all the information we needed.
-
-Try writing the route so that both tests pass.
diff --git a/testing/routes.md b/testing/routes.md
deleted file mode 100644
index a5a6e00..0000000
--- a/testing/routes.md
+++ /dev/null
@@ -1,135 +0,0 @@
-We can test server routes using [Supertest](https://github.com/visionmedia/supertest) and [tape](https://github.com/substack/tape).
-
-
-### Setting up
-
-We do this first and foremost by _exporting_ the Express `app` object from `server.js` (or wherever it happens to be defined):
-
-```
-// server.js
-var app = express()
-
-app.get('/example', function (req, res) {
- res.send('WOMBAT')
-})
-
-module.exports = app
-```
-
-Importantly, we want to put the `app.listen()` call in another file (`index.js`, for example). This allows our testing code to `require('./server.js')`. If we put the `.listen()` call in `server.js`, it will execute when the file is read and we don't actually want the server listening for connections while we're running our tests. This implies that we can tell things about our application without running it at all! Handy.
-
-`index.js` can be pretty simple:
-
-```
-// index.js
-
-var app = require('./server')
-var PORT = process.env.PORT || 3000
-
-app.listen(PORT, function () {
- console.log('Server listening on port: ', PORT)
-})
-```
-
-
-### Writing route tests
-
-By convention, Supertest is usually called from the variable name `request`.
-
-```js
-var request = require('supertest')
-var test = require('tape')
-
-var app = require('../server.js')
-
-test('/example returns WOMBAT', function (t) {
- // Arrange
- var expected = 'WOMBAT'
-
- // Act
- request(app)
- .get('/example')
- .end(function (err, res) {
- // Assert
- t.error(err)
- t.equal(res.text, expected)
- t.end()
- })
-})
-```
-
-Notice that we put our assertion inside a callback (the anonymous function passed to `.end`). Supertest will give us the response from the server here, or any error messages... this is a standard Node _error-first callback_. Supertest calls it for us when it's done requesting the `/example` route from our server.
-
-The `text/html` content sent back in the response can be found in the `res.text` property.
-
-In pseudocode, we might write:
-
-```
-SEND a request to the /example route
-WAIT for a response
-WHEN the response comes,
- COMPARE it with what we expected it to be
-```
-
-We can check more than just simple text returned from a route. We can test to see if there was an error, for example:
-
-```
- request(app)
- .get('/example')
- .end(function (err, res) {
- // Test fails if there's an error
- t.error(err)
- t.equal(res.text, expected)
- t.end()
- })
-```
-
-We can also check what the HTTP status code was that the server sent back (for example, 200 for _OK_ or 404 for _NOT FOUND_):
-
-```
- request(app)
- .get('/example')
- .expect(200)
-```
-
-
-### HTML
-
-We can use the [cheerio](https://github.com/cheeriojs/cheerio) library to test the HTML that gets sent back in a route response. cheerio can be used almost exactly like jQuery to select elements. Here's an example:
-
-```
-var cheerio = require('cheerio')
-var request = require('supertest')
-var test = require('tape')
-
-var app = require('../../server.js')
-
-test('/html-example has exactly one paragraph tag', function (t) {
- // Arrange
- var expected = 1
-
- // Act
- request(app)
- .get('/html-example')
- .expect('Content-Type', /html/)
- .end(function (err, res) {
- // First, we need to initialise cheerio with the HTML that was returned from our route
- var $ = cheerio.load(res.text)
-
- // Next, we get the array of all paragraph tags found in that response, and check its length.
- // The syntax is identical to jQuery checking the `document` object in a browser.
- var actual = $('p').length
-
- // Assert
- t.equal(actual, expected)
- t.end()
- })
-})
-```
-
-Of course, we can use cheerio to make much more complicated assertions. However, try to keep your tests from becoming too pedantic about what is returned from a route.
-
-> "Tell me, are there three question marks at the end of the third sentence in the fourth paragraph of the splash page?"
-
-What happens if that text gets changed during an update? Your tests will fail for no particularly good reason. Testing HTML output can tell us whether our template is rendering correctly, but it should be used in moderation.
-
diff --git a/testing/tape.md b/testing/tape.md
deleted file mode 100644
index 8db58b4..0000000
--- a/testing/tape.md
+++ /dev/null
@@ -1,25 +0,0 @@
-In earlier challenges we used `console.log` to assert whether our functions were working properly. This is acceptable in some situations, but quite restrictive. Luckily, lots of people have written lots of tools and modules to make testing a much easier experience.
-
-One of these is a framework called Tape, which is pretty awesome, and relatively simple compared to other testing libraries.
-
-Here's a basic Tape setup:
-
-```js
-var test = require('tape')
-
-test("test some basic js", function (t) {
- t.true(2+2 === 4, "addition works")
- t.equal(3*3, 9, "multiplication works")
-
- var testArray = ['dave', 'sharon']
- testArray.push('flora')
-
- t.deepEqual(testArray, ['dave', 'sharon', 'flora'], "pushing to arrays works")
-
- t.end()
-})
-```
-
-You'll probably want to improve the output of the test run with one of the recommended modules on the Tape website, for example `tap-diff` which turns tests red when they fail, and green when they pass. Remember, *red | green | refactor*!
-
-Have a look at this [simple demo]({{ book.cohort }}tape-demo) of a Tape setup if you want to have a quick play yourself.
diff --git a/testing/tdd.md b/testing/tdd.md
deleted file mode 100644
index 2426729..0000000
--- a/testing/tdd.md
+++ /dev/null
@@ -1,73 +0,0 @@
-TDD is a very popular and important programming practice. The idea is that you write a test for a feature/function/line of code _before you've actually written it_. By testing the outcome before you've written it, you plan more effectively exactly what that code needs to do.
-
-The goal is to write less code of higher quality, which is always great!
-
-*So how do we go about this madness?*
-
-> RED // GREEN // REFACTOR
-
-First, we should name our expectations in the form of a test:
-
-```js
-t.equal(addTwo(2), 4)
-```
-
-Here, I am asserting that when I pass `2` to the `addTwo` function, I expect the result to be `4`. This will of course fail (*red*), as I have yet to create this function.
-
-So, I create my function!
-
-```js
-function addTwo (number) {
- return 4
-}
-
-t.equal(addTwo(2), 4)
-```
-
-Now, my test will pass, turning it *green* (yay!). But if we take a wee look at this code, it's probably not going to work that well for values other than `2`, but let's write another test to be sure.
-
-```js
-t.equal(addTwo(4), 6)
-```
-
-Naturally this test will fail (*red*) because the `4` returned from `addTwo` does not equal the `6` we expected. So, let's get this test passing.
-
-```js
-function addTwo (number) {
- if (number === 2) {
- return 4
- }
-
- if (number === 4) {
- return 6
- }
-}
-
-t.equal(addTwo(2), 4)
-t.equal(addTwo(4), 6)
-```
-
-Now our tests are passing again (*green*), but looking at `addTwo` we can see this approach is getting unwieldy and isn't going to sustain us. That's a good indicator we should *refactor*. Refactoring is the process of improving the quality of the code without changing it's behaviour.
-
-```js
-function addTwo (number) {
- return number + 2
-}
-```
-
-We should always run the tests again after we've refactored to be sure we haven't accidentally broken something.
-
-```js
-t.equal(addTwo(2), 4)
-t.equal(addTwo(4), 6)
-```
-
-Passing, woohoo! Now we're ready to add another feature/expection in the form of another test that will initially fail (*red*), until we make it pass (*green*), all the while keeping our code quality high by *refactoring*. This is an extremely valuable practice that requires rigor and discipline, but pays huge rewards. Of course this was a trivial example, but the practice of TDD using red/green/refactor works in almost all scenarios.
-
-Why is test driven development so important?
-
-- Makes us explicitly name our expectations
-- Allows us to manage complexity in small chunks
-- Supports refactoring with confidence
-- Alerts us if we break something by mistake in the future
-
diff --git a/testing/testing-intro.md b/testing/testing-intro.md
index 14c1790..252fefd 100644
--- a/testing/testing-intro.md
+++ b/testing/testing-intro.md
@@ -1,11 +1,16 @@
+# An Introduction to Testing
+
On the client side watch for massive functions which are doing a lot of filtering and shuffling. Functions that are rendering templates are ideal targets for testing.
-Broadly there are two sorts of tests we write for the front end:
+Broadly there are two types of tests we write for the front end:
+
-#### Unit tests
+## Unit tests
These test single functions. Typically these might be functions which parse API responses for the data we care about, and handle edge cases. These you can easily test with tape.
-#### Integration tests
+
+## Integration tests
These test the integration of a number of features to test you've got a working system of parts. In practice, this is done by spinning up a browser, then having a robot click things and read the page to check for the correct responses. We'll be doing this later in the course.
+
diff --git a/testing/unit-testing-react.md b/testing/unit-testing-react.md
deleted file mode 100644
index 60e44f8..0000000
--- a/testing/unit-testing-react.md
+++ /dev/null
@@ -1,6 +0,0 @@
-The current popular framework for unit-testing components in React is Enzyme
-
-https://github.com/airbnb/enzyme
-
-Make sure you pay close attention to the way you render your component (shallow, render, mount).
-The docs on each method are worth reading to get a better idea.
diff --git a/testing/writing-tests.md b/testing/writing-tests.md
deleted file mode 100644
index 1f5f26e..0000000
--- a/testing/writing-tests.md
+++ /dev/null
@@ -1,34 +0,0 @@
-It's important that tests are clear, and state exactly what you expect the code to do. Very often, a developer starting on a new project will look at the the tests of a codebase to understand what is going on. It's important that your tests are as clear as possible.
-
-To enable this, it's common to write tests according to a simple formula. Each test should be made up of 3 distinct parts:
-
-1. **Arrange**
-2. **Act**
-3. **Assert**
-
-The *arrange* part represents the setup or context the code being tested needs in order for it to do what is expected of it. This part may be optional if there is no setup needed.
-
-The *act* part performs an action using the function you are testing. This part will always be in the test.
-
-Lastly, the *assert* part verifies the result (or behaviour) of the *act* matches what you expected. This uses a function that *asserts* an expectation: did we get the expected result, or something different? This part will also always be in the test.
-
-Let's see an example:
-
-```js
-var test = require('tape')
-
-test("can create a 2x2 matrix", function (t) {
- // arrange
- var expected = [[0,0], [0,0]]
-
- // act
- var result = makeEmptyMatrix(2)
-
- // assert
- t.deepEqual(result, expected)
- t.end()
-})
-```
-
-Let's have another play with this by revisting our simple tape demo, {{ book.cohort }}tape-demo.
-
diff --git a/tooling/process-argv.md b/tooling/process-argv.md
deleted file mode 100644
index ec4ab0f..0000000
--- a/tooling/process-argv.md
+++ /dev/null
@@ -1 +0,0 @@
-Process.argv is how you can see the arguments that were passed to a command line application. Checkout the [node docs](https://nodejs.org/docs/latest/api/process.html#process_process_argv) for more information.
diff --git a/tooling/scaffolding-intro.md b/tooling/scaffolding-intro.md
deleted file mode 100644
index e5079c4..0000000
--- a/tooling/scaffolding-intro.md
+++ /dev/null
@@ -1,15 +0,0 @@
-Like a factory function, but spins up a minimum project setup.
-
-Slush provides a cli tool which lets you use and create recipes: https://www.npmjs.com/package/slush
-
-Check out some generators: https://www.npmjs.com/search?q=slush (notice the query params)
-
-[slush-pages](https://www.npmjs.com/package/slush-pages) is a generator that Mikey made.
-Generators packages follow a naming convention `slush-xxx`, and when you're calling the generator you just use `xxx`.
-Mikey a bit of a name-grab with his package, which makes his generator easy to remember:
-
-```bash
-npm install -g slush slush-pages
-cd some_new_project_folder
-slush pages
-```
diff --git a/tooling/task-runners.md b/tooling/task-runners.md
deleted file mode 100644
index 2732c02..0000000
--- a/tooling/task-runners.md
+++ /dev/null
@@ -1,22 +0,0 @@
-_Task runners_ provide a way to script certain actions on our project or individual code files. The most notorious of these is [`make`](http://www.gnu.org/software/make/manual/make.html). Make is still relevant but its use in JavaScript applications is rare. Task runners such as [Gulp](http://gulpjs.com/) and [Grunt](http://gruntjs.com/) are very common. Task runners perform tasks to prepare our code for production deployments. _Bundlers_ provide a way to collect a number of different files and bundle them into a single file for deployment. But why are these operations needed?
-
-### Why do we need task runners and bundlers?
-
-Over the past 10 years web applications have moved more and more of the logic from the server to the browser. Today the majority of data retrieval, event handling, animation and view composition happens in the browser. To accomplish this we're using additional libraries.
-
-Until recently, JavaScript hasn't had a consistent way of separating JavaScript code across multiple files so they are easy to manage and easy to resolve dependencies across them:
-
-* Node.js uses CommonJS modules which use `module.exports` and `require`.
-* There have been other approaches that are more appropriate for the browser such as AMD (Asynchronous Module Definition).
-* The latest version of JavaScript now includes a module syntax for declaring and importing modules.
-
-In order for bundling to work, it needs to be able to locate each of a file's dependencies and understand their relationships.
-
-In addition to the increasing complexity brought on by added functionality and the need to reconcile multiple module loading mechanisms, there are now many languages that _transpile_ to JavaScript such as CoffeeScript, TypeScript, and the latest version of JavaScript, ECMAScript 6/2015. CSS also has intermediary formats that require a _build_ for they can be used in a browser: SASS, LESS and SCSS are a few of the common choices. Transpiling file from these format is one of the jobs of the task runner.
-
-However, even after your code has been bundled, there are usually a couple of other steps that will need to be taken before the code is ready to be deployed and used in an application:
-
-* _Minification_ is the process of removing all unnecessary characters and source code from the original without changing its functionality. This process can require a lot of intelligence about the code.
-
-* _Concatenation_ is like bundling, but perhaps less intelligently. The goal of this process is about reducing the number of HTTP requests performed by the browser in order to get all of the assets needed by the application.
-
diff --git a/version-control/git-best-practices.md b/version-control/git-best-practices.md
deleted file mode 100644
index 2d4d470..0000000
--- a/version-control/git-best-practices.md
+++ /dev/null
@@ -1,56 +0,0 @@
-**Git** is beautiful version control software - it manages and records changes to files and documents in a project. This means that it is possible to:
-
- 1. Have one master copy of the project
- 2. Give everyone access to a copy of the project that they can work on
- 3. Have many people working on the same project without messing up each others work
- 4. Roll back to previous versions of the project
-
-**GitHub** is an online interface to easily use Git to collaborate with many people. GitHub hosts your projects online and adds some extra functionality to Git such as 'issues' and 'pull requests'.
-
-**Git vs GitHub**
-Git is the local tool. GitHub is the remote service for projects that use Git.
-
-**Wow. What?**
-If everything seems unclear now, don't worry. Time and practice are the best way to let things sink in. It'll make more sense using Git and GitHub in your own projects.
-
-
-## Prerequisites
-
-- GitHub account
-- [GitHub basics 1]({{ book.phase0.concept }}github-basics)
-- [Command line basics]({{ book.phase0.concept }}command-line-basics)
-
-
-## Capabilities
-
-You can use Git and GitHub to collaborate on projects. You can:
-
- - Create GitHub repositories
- - Clone remote repositories
- - View the current state of a branch
- - Understand local and remote repositories
- - Create branches and switch between different ones
- - Push to and pull from remote repositories
- - **Create 'pull requests'**
- - Write good commit messages
- - Use Git to review your project's history
- - Handle Git auto-merge commit messages
-
-
-## Resources
-
-Use these resources (and others you find) to learn the capabilities above! There will be other capabilities in the resources - focus on learning the capabilities above, you'll learn the rest when you need it.
-
-- [Git beginners steps part 2 (Interactive)]({{ book.phase0.resource }}git-basics-INTERACTIVE)
-- [Git merge messages (ARTICLE)]({{ book.phase0.resource }}git-merge-message-ARTICLE)
-- [GitHub Pull, Branch, Merge (Video)]({{ book.phase0.resource }}github-pull-branch-merge-team-VIDEO)
-- [GitHub/Git glossary (Text)]({{ book.phase0.resource }}git-glossary-TEXT)
-- [How to write a Git commit message (Article)]({{ book.phase0.resource }}git-commit-messages-ARTICLE)
-- [Git for beginners (Article)]({{ book.phase0.resource }}git-basics-ARTICLE)
-- [Example GitHub workflows and common errors (Text/Tutorial)]({{ book.phase0.resource }}github-phase-0-workflow-TUTORIAL)
-
-
-## Further study
-
-- [Intermediate Git](https://www.atlassian.com/git/tutorials/comparing-workflows)
-