` to which you will need to dynamically append HTML elements through your JavaScript code in `index.js`.
-
-2. Open `index.js`. This file contains a starter set of code for you to expand. It contains the following three functions:
-
- | Function | Description |
- | ----------------- | ------------------------------------------------------------------------------------------------------------ |
- | `fetchJSON` | Uses `XMLHttpRequest` to fetch JSON data from an API end point. This function uses an asynchronous callback. |
- | `createAndAppend` | A utility function for easily creating and appending HTML elements. |
- | `main` | Contains the start-up code for the application. |
-
- `index.js` also contains a variable with the URL required for fetching information about the HYF repositories:
-
- ```js
- const HYF_REPOS_URL =
- 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100';
- ```
-
-3. Open the `index.html` file in your browser. You will see an unordered list with the names of the HYF repositories.
-
-4. Review the `main()` function in `index.js` and examine how this code fetches the JSON data and calls renders the data as unordered list in the web page.
-
-5. Take a look at the API URL:
-
-```
-https://api.github.com/orgs/HackYourFuture/repos?per_page=100
+2. It displays those repositories in an alphabetically-ordered list. When a user clicks on any of the repository names it will show more details about it.
+
+In the course of the next 3 weeks you'll be writing the necessary code to make all of this work!
+
+### 4.1 Requirements
+
+To get started, make sure you're in the right GIT branch: `week1-[YOURNAME]`. Then, navigate to the `hackyourrepo-app` folder and become familiar with the files there.
+
+This week you're required to (1) setup the HTML structure of the application. In addition, you are expected to (2) style the application to make it user-friendly.
+
+Here are the requirements for the HTML:
+
+- Include 3 `
` tags
+- Include a `` tag
+- Use the following placeholder data:
+
+```js
+const placeholderRepos = [
+ {
+ name: 'SampleRepo1',
+ description: 'This repository is meant to be a sample',
+ forks: 5,
+ updated: '2020-05-27 12:00:00',
+ },
+ {
+ name: 'AndAnotherOne',
+ description: 'Another sample repo! Can you believe it?',
+ forks: 9,
+ updated: '2020-05-27 12:00:00',
+ },
+ {
+ name: 'HYF-Is-The-Best',
+ description:
+ "This repository contains all things HackYourFuture. That's because HYF is amazing!!!!",
+ forks: 130,
+ updated: '2020-05-27 12:00:00',
+ },
+];
```
-This URL is special, as it gives us data in JSON format (Try it out in your browser!). This type of URL is also known as an `endpoint`, an address that we can use to send a request to in order to get data. Learn more about endpoints [here](https://smartbear.com/learn/performance-monitoring/api-endpoints/).
-
-Note the query string `?per_page=100` in the above URL. If you don't specify this `query string` you will only get the first 30 repositories (the default `per_page` is 30, which we know because it says so in the [API documentation](https://developer.github.com/v3/#pagination)).
-
-### Week 1 Assignment
-
-The assignment for this week is to produce a functional application that looks similar to Figure 1:
-
-
-
-Functionally, the application should do the following:
-
-1. Make an API call to the endpoint: https://api.github.com/orgs/HackYourFuture/repos?per_page=100
-2. Display the first 10 items in the HTML file (write JavaScript to add element to the DOM)
-3. Show feedback when an error has happened
-
-Modify the following files:
-
-**1. `index.js`**
-
-- Add new functions and modify function `main()` as you see fit.
-- Render network errors to the DOM (see Figure 2 below for an example). Do not use `console.log` as regular users will not see the console output. Instead, create an element that displays the error message in the DOM. Use the predefined `alert-error` class from `style.css` to style your error. It should look like this:
-
-
-
-Figure 2. Rendering of network errors.
-
-**2. `style.css`**
-
-- Add your own CSS styling. Use `style.css` for all of your CSS rules to style the `index.html`. Make sure your UI is responsive. Try it with Chrome Developer Tools in the browser, using a mobile phone format and a tablet format, portrait and landscape.
-
- **You are not allowed to use a CSS library such as Bootstrap.**
-
-**Hints:**
-
-- To sort the list repositories use [`.sort()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) and [`.localeCompare()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare).
-
-- Use CSS media queries, percentage values and [Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) to make the UI responsive.
+Here are the requirements for the CSS:
-- To force a `404` network error so that you can test the rendering of errors, change the URL to make an invalid GitHub request, e.g. append an `x` to `orgs`: `orgsx`.
+- Make use of `flexbox`
+- Make use of `media-queries` and `calc()` to make the page responsive ([mobile, tablet, desktop](https://tinyurl.com/yc5zmste))
-Good luck!
+Other than this you can create your own version of the page!
## **SUBMIT YOUR HOMEWORK!**
diff --git a/Week1/README.md b/Week1/README.md
index b6b640443..49d35d1cc 100644
--- a/Week1/README.md
+++ b/Week1/README.md
@@ -9,6 +9,7 @@ These are the topics for week 1:
- Connecting with APIs
2. Asynchronous JavaScript and XML (AJAX)
- JavaScript Object Notation (JSON)?
+ - Stringifying and parsing JSON
- XMLHttpRequest (XHR)
3. Modules & Libraries
- What's a module?
@@ -18,20 +19,27 @@ These are the topics for week 1:
## 1. Application Programming Interface (API)
-Whenever we talk development we'll inevitably end up talking about Application Programming Interfaces, or APIs for short. But what is all the fuss about?
+Whenever we talk about software development, we'll inevitably end up talking about `Application Programming Interfaces`, or APIs for short. But what is all the fuss about?
The first thing we need to understand is that API means different things to different people. Some people use it to refer to a complete application (frontend + backend), others use it to only refer to the server, or there's even people who use it to refer to any part of an application (i.e. "frontend API"/"server API")
For our purposes it's useful to stick to one definition, while keeping in mind that others will use it differently. Here's the definition we'll use:
```markdown
-An API is any software that contains a part that's accessible from an outside source: i.e. open to requests from the client (whether it's a from a frontend or another server). That part that's accessible is the "interface" of that software.
+An Application Programming Interface (API) is an interface to an application. It's the point of connection for any other application, in order to communicate with it. The API defines the terms of how to connect to it.
```
-You can think of an API in the following manner: Imagine you want to rent out a room in your house through Airbnb. Everyone who has a key to this room can freely enter and make use of whatever is inside. In this analogy the house is the API, while the room that's rented out is the "interface".
+You can think of an API as a wall socket:
+
+
+
+As you can see on the image, the wall socket has a certain shape. This shape defines in what way something can connect to it. If you were to use a plug that had a different shape, it would never fit and thus never be able to connect. But if you had a plug that was in the correct shape, you got plug it in and proceed to connect to whatever is behind the socket (which in this case is the service of electricity).
+
+In a way, you could say that an API is the frontend to an application. It's similar to the frontend part of a website. The biggest difference is, however, that instead of giving a way for human users to interact with it, an API gives a way for other applications to interact with it.
For more research, check out the following resources:
+- [APIs Are Like User Interfaces - Just With Different Users in Mind](https://www.programmableweb.com/news/apis-are-user-interfaces-just-different-users-mind/analysis/2015/12/03)
- [What are APIs - series](https://www.youtube.com/watch?v=cpRcK4GS068&list=PLcgRuP1JhcBP8Kh0MC53GH_pxqfOhTVLa)
- [APIs for Beginners](https://www.youtube.com/watch?v=GZvSYJDk-us)
@@ -39,97 +47,213 @@ For more research, check out the following resources:
There are 2 different types of APIs: **public** and **private** APIs.
-An API is **public** when software companies publish parts of their software to be freely used by developers from the outside world. If you were to integrate the Facebook API as a login sytem in your application, you would be using their API as a public API.
+An API is **public** when software companies publish parts of their software to be freely used by developers from the outside world. If you were to integrate the Facebook API as a login system in your application, you would be using their API as a public API.
Conversely, there are also **private** APIs: software companies that grant access to parts of their backend applications to internal developers only, in order to develop new services to be used either internally or for the outside world.
-In reality, there are way more private than public APIs. This is because it's usually in the company's best interest to keep their code base hidden from the public eye: it would be like giving your secret recipe away for nothing.
+In reality, there are way more private than public APIs. This is because it's usually in the company's best interest to keep their code base hidden from the public eye: it would be like giving your secret recipe away for free.
-Keep this in mind: **in the real world programming is a means to serving a business end**. In this course you're learning how to program, to make nice-looking functional applications. However, this is always done within a business context. This is to say: does this software lead to making more money/gaining more popularity/or the achievement of any other business goal?
+Keep this in mind: in the real world **programming is only a means to serving a business end**. In this course you're learning how to program, to make nice-looking, well-functioning applications. However, this is always done within a business context. This is to say: does this software lead to making more money/gaining more popularity/or the achievement of any other business goal?
- [The Business Impact of Private, Partner and Public APIs](https://www.youtube.com/watch?v=Bk50AYGvs-g)
### Connecting with APIs
-A big part of what applications do is **moving data from one place to another**. Let's say you are on the HackYourFuture website and feel like donating some money. First of all, that's very nice of you! You head out to the website and click on the donate button. You type in the amount and click on "donate". You'll notice you immediately get redirected to a different website, namely Mollie.com. How did Mollie know how to do this?
+A big part of what applications do is **moving data from one place to another**. Let's say you are on the HackYourFuture website and feel like donating some money. First of all, that's very nice of you! You head out to the website and click on the donate button. You type in the amount and click on "donate". You'll notice you immediately get redirected to a different website, namely checkout.stripe.com. How did Stripe know how to do this?
+
+It's because the HackYourFuture website sends a **HTTP Request** to Stripe. The request basically says "Hey Stripe, some user from the HackYourFuture site wants to make a digital payment, can you handle that?". As a response Stripe answers "Of course, send the user to this specific URL and I'll take it from there!".
+
+> Anytime a request to an API is made this is called a `HTTP Request`. However, in practice people use different terms for the same thing. Synonyms for `HTTP Request` are `API call/request`, `Network call/request`, `Web request/call` or`HTTP call`. Which do you prefer?
+
+A HTTP Request has to be made using a special method. The browser gives us two of them: `XMLHttpRequest` and `Fetch API`. `XMLHttpRequest` (or XHR for short) is the older, more verbose method. It looks like this:
+
+```js
+// 1. Create a new XMLHttpRequest object
+const xhr = new XMLHttpRequest();
+
+// 2. Configure it: GET-request for the URL /article/.../load
+xhr.open('GET', '/article/xmlhttprequest/example/load');
+
+// 3. Send the request over the network
+xhr.send();
+
+// 4. This will be called after the response is received
+xhr.onload = function () {
+ if (xhr.status != 200) {
+ // analyze HTTP status of the response
+ alert(`Error ${xhr.status}: ${xhr.statusText}`); // e.g. 404: Not Found
+ } else {
+ // show the result
+ alert(`Done, got ${xhr.response.length} bytes`); // response is the server
+ }
+};
+
+xhr.onprogress = function (event) {
+ if (event.lengthComputable) {
+ alert(`Received ${event.loaded} of ${event.total} bytes`);
+ } else {
+ alert(`Received ${event.loaded} bytes`); // no Content-Length
+ }
+};
+
+xhr.onerror = function () {
+ alert('Request failed');
+};
+```
-It's because the HackYourFuture website sends an **API call** to Mollie. The request basically says "Hey Mollie, some user from the HackYourFuture site wants to make a digital payment, can you handle that?". As a response Mollie answers "Of course, send the user to this specific URL and I'll take it from there!".
+This way of making HTTP Requests is outdated (and not recommended to use), but it's good to be aware of it as you might still see it in old code bases.
-> Anytime a request to an API is made this is called an `API call`. However, in practice people use different terms for the same thing. Synonyms for `API call` are `API request`, `Network call/request` or`HTTP call/request`. Which do you prefer?
+The newer way of making HTTP Requests involves using the `Fetch API`. You'll learn more about that next week!
-For further study of how to make API calls, check out the following resources:
+For further study of how to make HTTP Requests, check out the following resources:
- [Working with APIs in JavaScript](https://www.youtube.com/watch?v=ecT42O6I_WI)
- [Making HTTP Requests in JavaScript](https://www.kirupa.com/html5/making_http_requests_js.htm)
## 2. Asynchronous JavaScript and XML (AJAX)
-AJAX is the idea that data can be loaded into a webpage without refreshing the entire website. The term is an acronym for `asynchronous JavaScript and XML`. Let's pick that apart:
+AJAX is the idea that data can be loaded into a webpage without refreshing the entire website. It's a **web development technique** when building websites, NOT a technology or programming language.
-- Asynchronous JavaScript refers to the fact that an asynchronous function is used. As we've learned in the previous module, an asynchronous function allows the browser to do multiple things simultaneously.
+The term is an acronym for `asynchronous JavaScript and XML`. Let's pick that apart:
+
+- Asynchronous JavaScript often refers to the act of using an asynchronous function to make an HTTP Request to fetch data. As we've learned in the previous module, an asynchronous function allows the browser to do multiple things simultaneously. In this way we fetch data in the background, while the user is still able to navigate the webpage.
- XML is a data format used to send information from a server to a client, and vice versa.
-The name AJAX is actually a misnomer, because XML isn't really used any more. Instead, another data format has taken its place: `JSON`.
+This technique was used back in the days when the web wasn't that advanced. Back then we used XML is the standard format we used to structure our data in. Nowadays we have replaced it with another data format: `JSON`.
+
+### JavaScript Object Notation (JSON)
+
+`JSON` stands for JavaScript Object Notation and is a very JavaScript-like data format. Here's a small example:
+
+```json
+{
+ "first name": "Noer",
+ "last name": "Paanakker",
+ "age": 28,
+ "address": {
+ "street address": "Strekkerweg 79",
+ "city": "Amsterdam",
+ "postal code": "1033 DA"
+ }
+}
+```
+
+If you look closely it almost looks exactly like a regular JavaScript object. There are 2 big differences: (1) in a JSON object everything is turned into a string (als known as "stringified"), and (2) it's not tied to the JavaScript language. Actually, many other languages can work with JSON!
+
+In AJAX we make a HTTP Request to a web server, that then responds back with information to be used in the frontend. Generally speaking, this data will be send in `JSON` format. The web server "stringifies" (makes into a string) the data to be send first before it sends it.
-### JSON
+### Stringifying and parsing JSON
-In AJAX we make a client request to a web server, that in response sends us back information to be used in the frontend. Generally speaking, this data will be send in `JSON` format.
+JSON is the modern web standard data format to send and receive data in. In order to make something into JSON format we need to `stringify` it: make the whole object into one string. Luckily, JavaScript gives us a way to do this:
-So, technically speaking, the term would actually be AJAJ. However, the industry has decided to stick with the term AJAX to refer to these processes.
+```js
+const noer = {
+ firstName: 'Noer',
+ lastName: 'Paanakker',
+};
+const noerJSON = JSON.stringify(noer);
+
+console.log(noerJSON); // Result: {"firstName":"Noer","lastName":"Paanakker"}
+```
+
+Here's another way of looking at the "stringifying" process: let's say you want to send your mother a gift, a brand new HackYourFuture T-shirt. Would you just put the shirt right into the mailbox, like that? Of course not! You would wrap it up nicely and put it into a box. Then you put it in the mailbox and off it goes!
+
+This act of putting something into a box is what's happening when we `stringify` data (either on the client-side or server-side).
+
+After the JSON data has been send, the receiver has to be able to interpret it. This process of making JSON interpretable by the programming language within that environment is called `parsing`. As we're using JavaScript, it doesn't seem like a big stretch. But what if we're using some other programming language like Python or Java?
+
+To follow our analogy, this is basically your mother unpacking her T-shirt from out of the box you put it in!
+
+Again, in JavaScript we can use another method gained from the global `JSON` object in order to `parse` our JSON data:
+
+```js
+const noer = {
+ firstName: 'Noer',
+ lastName: 'Paanakker',
+};
+
+const noerJSON = JSON.stringify(noer);
+
+const noerParsed = JSON.parse(noerJSON);
+
+console.log(noerParsed); // Result: { firstName: 'Noer', lastName: 'Paanakker' };
+```
+
+Nowadays we use JSON to perform asynchronous operations using JavaScript. So, technically speaking, the term would actually be AJAJ. However, the industry has decided to stick with the term AJAX to refer to these processes. Keep that in mind whenever someone asks you about it!
+
+Go through the following to learn more about JSON and AJAX:
+
+- [JSON - Introduction](https://www.w3schools.com/js/js_json_intro.asp)
+- [Learn JSON in 10 Minutes](https://www.youtube.com/watch?v=iiADhChRriM)
- [JSON Crash Course](https://www.youtube.com/watch?v=wI1CWzNtE-M)
### XMLHttpRequests (XHR)
-In order to make an AJAX request we have to make use of a special type of object, called `XMLHttpRequest`(shortened to XHR). It's an object predefined for us by the `window` object in the browser.
+Traditionally, in order to make use of the AJAX technique we need to make use of a special type of object, called `XMLHttpRequest`(shortened to XHR). It's an object predefined for us by the `window` object in the browser.
> The `window` object is the most top-level object available to us in the browser. It contains the `document`, which contains all the HTML/CSS and JavaScript we write. Besides this, the `window` also contains a lot of other things we use when writing frontend code: `setTimeout()`, `alert()` and it even contains a reference to the `console` (from which we get `console.log()`). Try it out in the console if you want to see for yourself!
-By creating a new instance of this object we can start making AJAX requests!
+By creating a new instance of this object we can start making HTTP requests!
```js
const xhr = new XMLHttpRequest();
```
-Making XHR requests is the primary way of making API calls. It allows us to send and retrieve data from other services.
+Making XHR requests is the primary way of making HTTP Requests. It allows us to send and retrieve data from other services.
+
+However, this method is outdated and we use more modern means now (using the `Fetch Web API` or a solution like `axios`). You will learn about that next week!
Check the following resources to learn more about XHR.
- [XMLHttpRequest](https://github.com/hackyourfuture/fundamentals/blob/master/fundamentals/XMLHttpRequest.md)
- [AJAX Crash Course](https://www.youtube.com/watch?v=82hnvUYY6QA)
-- [Sending JavaScript Http Requests with XMLHttRequest](https://www.youtube.com/watch?v=4K33w-0-p2c)
+- [Sending JavaScript HTTP Requests with XMLHttRequest](https://www.youtube.com/watch?v=4K33w-0-p2c)
## 3. Modules & Libraries
### What's a module?
-A `module` is a part of a program that contains one or more functionalities. For example, a single function that has only 1 job could be considered a module. When developing applications you'll always be writing multiple functionalities in order for your software to work as expected. These can be written all in one file, and it would fine. The browser/operating system would be able to interpret and execute it anyway. But for you, the human, it's very hard to keep overview of what is happening at what level of the application.
+A `module` is a part of an application that contains usually a single functionality. For example, a single function that has only 1 job could be considered a module. For example:
+
+```js
+function addNums(num1, num2) {
+ return num1 + num2;
+}
+```
+
+If this little function has its own dedicated `.js` file and you can import it into another file, it's a module!
+
+When developing applications you'll always be writing multiple functionalities in order for your software to work as expected. These can be written all in one file, and that would still work. The browser/operating system would be able to interpret and execute it anyway. But for you, the human, it's very hard to keep overview of what is happening at what level of the application. Can you only imagine having to look through one big file of 1000's of lines of code, just to find
-In order to keep a better overview, we can choose to **modularize** our application: split it up into smaller parts that, in theory, all work independently.
+In order to keep a better overview, we can choose to **modularize** our application. This means: splitting it up into smaller parts (modules) that, in theory, all work independently.
However, creating better overview is not the only reason. Among other reasons, modules make a developer's job easy by:
-- Allowing them to focus on only one area of the functionality of the software application
-- Isolating individual blocks of code, in case anything breaks
+- Making the application easier to maintain, by making it more readable and thus easier to modify
+- Isolating individual blocks of code, in order to make errors more easily traceable
- Encouraging the developer to write code in a way that makes it reusable
For more information about this, go through the following:
+- [Introduction to Modular Design](https://www.youtube.com/watch?v=20JP8w6_nVA)
+- [JavaScript Patterns: The Traditional Module Pattern](https://www.youtube.com/watch?v=SKBmJ9P6OAk)
+- [JavaScript Modules in 100 Seconds](youtube.com/watch?v=qgRUr-YUk1Q)
- [JavaScript Modules: From IIFEs to CommonJS to ES6 Modules](https://www.youtube.com/watch?v=qJWALEoGge4)
### What's a library?
If you've ever written code you know how easy it is to duplicate it: you just copy and paste it.
-Modules are small blocks of code that make up a functionality. But what if you have a bunch of modules that collectively aim to solve a bigger problem, like creating a [Single Page Application](https://en.wikipedia.org/wiki/Single-page_application)?
+Modules are small blocks of code that make up a functionality. But what if you have a bunch of modules that collectively aim to solve a bigger problem, like creating [data visualizations](https://d3js.org/) or make DOM manipulation easier ([jQuery](https://jquery.com/))?
-For this we use a `library`: a set of code that a developer (or a team of developers) has written in order to solve these bigger problems within an application. A library, typically, contains a collection of modules that work together to solve a big problem.
+For this we use a `library`: code that a developer (or a team of developers) has written in order to solve these bigger problems within an application. A library, typically, contains a collection of modules that work together in order to solve a bigger problem.
-> Like many things in programming, people use various terms to describe the same thing. In the case of `library`, you'll often hear it spoken of as `package` or `namespace`.
+> Like many things in programming, people use various terms to describe the same thing. In the case of `library`, you'll often hear it spoken of as `package`, `namespace` or `dependency`.
Why do we use libraries? We use them to help us make building applications easier. Think of it like building a house: in theory you could do it all by hand. But as you can imagine, this is highly inefficient and time-consuming. So instead we use tools to help us out. These can be small tools (like a hammer or screwdriver) or bigger ones (like a concrete mixer or wheel barrow).
-In the real-world companies use libraries all the time. They either make them themselves, or they make use of public ones. If the original developers of a library have published their code, through a platform like [npmjs.com](https://www.npmjs.com/) for example, it can legally be used in custom applications. This is called **open-source**: the source code is open for any to look into, use and modify to their own needs.
+In the real-world developers use libraries all the time. They either make them themselves, or make use of public ones. If the original developers of a library have published their code, through a platform like [npmjs.com](https://www.npmjs.com/) for example, it can legally be used in custom applications for free. This is called **open-source**: the source code is open for any to look into, use and modify to their own needs.
Examples of common JavaScript libraries are the following:
@@ -146,11 +270,13 @@ When researching these it's important to ask yourself two questions:
For further study, check the following:
+- [Code Libraries](https://www.youtube.com/watch?v=FQAQTXE_vt4)
- [JavaScript Libraries](https://www.youtube.com/watch?v=uq7omoxwA7A)
+- [https://www.youtube.com/watch?v=24GF5MVEEjE](https://www.youtube.com/watch?v=24GF5MVEEjE)
### An example of a library
-In a previous section we discussed APIs and the importance of being able to make API calls. We have seen that we can use the XHR object to do so. In this section we'll discuss a `library` that makes this process easier for us. It's called [axios](https://github.com/axios/axios), a JavaScript library that allows us to make API calls in an easier way.
+In a previous section we discussed APIs and the importance of being able to make HTTP Requests so that we can communicate with them. We have seen that we can use the `XHR` object to do so. In this section we'll discuss a `library` that makes this process easier for us. It's called [axios](https://github.com/axios/axios), a JavaScript library that allows us to make HTTP Requests in an easier way.
Here's what it looks like in action:
@@ -160,11 +286,11 @@ const axios = require('axios'); // We have to load in the library first
// Make a GET request to get user data from the Pokemon API
axios
.get('https://pokeapi.co/api/v2/pokemon')
- .then(function(response) {
+ .then(function (response) {
console.log(response);
// Do something with data
})
- .catch(function(error) {
+ .catch(function (error) {
console.log(error);
// Do something with error
});
@@ -173,11 +299,11 @@ axios
Any library that exists is developed to solve some problem. The main problems `axios` aims to solve are the following:
1. how to make an `HTTP request` in an easier way
-2. how to write more readable asynchronous code.
+2. how to write more readable asynchronous code
Here's how `axios` solves problem 1:
-- It abstracts away/"simplifies")the XHR logic needed to make an API call and wraps it inside of functions that are more descriptive (like `axios.get` or `axios.post`, to indicate a GET and POST request)
+- It abstracts away/simplifies the XHR logic needed to make a HTTP Request and wraps it inside of functions that are more descriptive (like `axios.get` or `axios.post`, to indicate a GET and POST request)
Here's how `axios` solves problem 2:
@@ -187,7 +313,7 @@ Here's how `axios` solves problem 2:
Now that you've learned about the utility of libraries, let's talk a little about how to approach using a library. Keep in mind that this is not the only way to do it, but it will set you off on a good start.
-1. **Do your research**. Doing research means finding out more about the library. Is it new? Is it fully functional? What do other people say about using it? Is it backed by the community? Does the library have a GitHub page?
+1. **Do your research**. Doing research means finding out more about the library. Is it new? Is it fully functional? What do other people say about using it? Is it backed by a sizable developer community? Does the library have a GitHub/NPM page?
2. **Read the documentation**. If code has been published for everyone to use, most likely the developers have written a guide on how to use it. This is called `documentation`. After doing your research delve into it and try to figure out what the philosophy and usages of the library are.
3. **Try out a basic example**. A basic example can usually be found in the documentation. Copy and paste it into an empty file for yourself and try it out. It's best to try it out in isolation first, so that you can learn exactly what makes it work. Then slowly start playing around with it: change names, move lines of code.
4. **Try to integrate it with your own code base**. Once you've tried it out it's time integrate it into your own code. Figure out where to best put it. The documentation can help you out with that. Look at other developer's code and see how they use it. Watch videos or read articles online.
diff --git a/Week1/assets/hyf-github.png b/Week1/assets/hyf-github.png
index 393bc0288..eef2e9692 100644
Binary files a/Week1/assets/hyf-github.png and b/Week1/assets/hyf-github.png differ
diff --git a/Week2/MAKEME.md b/Week2/MAKEME.md
index 8212430f6..d4f082dee 100644
--- a/Week2/MAKEME.md
+++ b/Week2/MAKEME.md
@@ -15,7 +15,62 @@ Let's start this week off with some interactive exercises! Visit the following l
## **2. JavaScript exercises**
-**_No exercises this week_**
+> Inside of your `JavaScript3` fork and inside of the `Week2` folder, create a folder called `homework`. Inside of that folder, create a folder called `js-exercises`. For all the following exercises create a new `.js` file in that folder (3 files in total). Make sure the name of each file reflects its content: for example, the filename for exercise one could be `getName.js`.
+
+**Exercise 1: John who?**
+
+Take a look at the following function (and try it out in your console):
+
+```js
+const getAnonName = (firstName, callback) => {
+ setTimeout(() => {
+ if (!firstName)
+ return callback(new Error("You didn't pass in a first name!"));
+
+ const fullName = `${firstName} Doe`;
+
+ return callback(fullName);
+ }, 2000);
+};
+
+getAnonName('John', console.log);
+```
+
+Rewrite this function, but replace the callback syntax with the Promise syntax:
+
+- Have the `getAnonName` function return a `new Promise` that uses the `firstName` parameter
+- If the Promise `resolves`, pass the full name as an argument to resolve with
+- If the Promise `rejects`, pass an error as the argument to reject with: "You didn't pass in a first name!"
+
+**Exercise 2: Is it bigger than 10?**
+
+Write a function called `checkDoubleDigits` that:
+
+- Takes 1 argument: a number
+- Returns a `new Promise`
+- If the number is bigger than 10, resolve with the string: "The number is bigger than 10!"
+- If the number is smaller than 10, reject with the error: "Error! The number is smaller than 10..."
+
+**Exercise 3: Gotta catch 'em all**
+
+> Inside of your `homework` folder, create another folder called `pokemon-app`. There, create an `index.html` and `script.js` file
+
+Let's catch all original 151 Pokemon in our own little web application! Here's an example of what you'll be building for this exercise:
+
+
+
+In this exercise you're going to do several things:
+
+1. Create and append DOM elements using JavaScript only
+2. Fetch data twice from a public API [PokeAPI](https://pokeapi.co/)
+3. Display the results in the DOM.
+
+Here are the requirements:
+
+- Create 3 functions: `fetchData`, `addPokemonToDOM` and `main`
+- The `main` function executes the other functions and contains all the variables
+- In the `fetchData` function, make use of `fetch` and its Promise syntax in order to get the data from the public API
+- Execute the `main` function when the window has finished loading
## **3. Code along**
@@ -27,57 +82,38 @@ Enjoy!
## **4. PROJECT: Hack Your Repo II**
-The assignment this week is to enhance your application to look similar to the following:
-
-
-
-As you can see, it looks different from the one from last week. This week we'll be rewriting most of our code to now show information for a single repository and also list its contributors (instead of the details for all repositories). A user should be able to search for all repositories in the account and select the one they want more information on.
+> This week we'll continue building on our work from last week. Make sure to navigate to the `hackyourrepo-app` folder and start based on the code you wrote!
-### Week 2 Assignment
+This week we'll do a couple of things:
-The enhanced application should fulfill the following requirements:
+1. We'll remove our HTML elements and remake them using JavaScript only!
+2. We'll replace our placeholder data with real data from the GitHub API
+3. We'll display this data in a separate column of the user interface
-1. The list of repositories in the `select` element should be sorted (case-insensitive) on repository name.
-2. At start-up your application should display information about the first repository as displayed in the `select` element.
-3. When the user changes the selection, the information in the web page should be refreshed for the newly selected repository.
-4. You should be able to click on the repository name of the selected repository to open a new browser tab with the GitHub page for that repository.
-5. You should be able to click on a contributor to open a new browser tab with the GitHub page for that contributor.
-6. Your UI should be responsive. Try it with Chrome Developer Tools in the browser, using a mobile phone format and a tablet format, portrait and landscape.
-7. The `XMLHttpRequest` in the `fetchJSON` function should be replaced with `fetch`. Hint: Because `fetch` returns a promise out of the box there is no need create a Promise yourself with `new Promise(...)`.
+On the surface, it'll look exactly the same. But functionally, it'll based around JavaScript only!
-**Hints:**
+Here are the requirements:
-- The `index.html` file can be divided into several components:
+- Remove the HTML elements you created last week, and only keep the `
-
-
-
-
-
-
-
+
diff --git a/hackyourrepo-app/script.js b/hackyourrepo-app/script.js
new file mode 100755
index 000000000..a2206d1ed
--- /dev/null
+++ b/hackyourrepo-app/script.js
@@ -0,0 +1,5 @@
+"use strict";
+
+/*
+ Write here your JavaScript for HackYourRepo!
+*/
diff --git a/hackyourrepo-app/style.css b/hackyourrepo-app/style.css
new file mode 100755
index 000000000..5b3acae8a
--- /dev/null
+++ b/hackyourrepo-app/style.css
@@ -0,0 +1,3 @@
+/*
+ Write here your CSS rules for HackYourRepo!
+*/
diff --git a/hand-in-homework-guide.md b/hand-in-homework-guide.md
index 35070caec..710ff3cf3 100644
--- a/hand-in-homework-guide.md
+++ b/hand-in-homework-guide.md
@@ -6,7 +6,9 @@ In this module you'll submit your homework only using GIT and GitHub.
## 1. GitHub homework guide
-Follow the walkthrough to learn how to submit your homework for each week:
+
+
+Watch the video (by clicking the image) or go through the following walk-through to learn how to submit your homework:
ONE TIME ONLY (START OF EVERY MODULE)
diff --git a/homework-classes/App.js b/homework-classes/App.js
deleted file mode 100755
index 8788f8b85..000000000
--- a/homework-classes/App.js
+++ /dev/null
@@ -1,56 +0,0 @@
-'use strict';
-
-{
- const accounts = {
- hyf: {
- name: 'HackYourFuture',
- type: 'org',
- },
- microsoft: {
- name: 'Microsoft',
- type: 'org',
- },
- jim: {
- name: 'remarcmij',
- type: 'user',
- },
- };
-
- const { Model, HeaderView, RepoView, ContributorsView, ErrorView } = window;
- const { createAndAppend } = window.Util;
-
- class App {
- constructor(account) {
- const containers = App.renderContainers();
-
- const model = new Model(account);
- const fetchData = model.fetchData.bind(model);
-
- model.subscribe(new HeaderView(account, containers.header, fetchData));
- model.subscribe(new RepoView(containers.repo));
- model.subscribe(new ContributorsView(containers.contributors));
- model.subscribe(new ErrorView(containers.error));
-
- fetchData();
- }
-
- static renderContainers() {
- const root = document.getElementById('root');
- const header = createAndAppend('header', root, { class: 'header' });
- const error = createAndAppend('div', root);
- const main = createAndAppend('main', root, {
- class: 'main-container',
- });
- const repo = createAndAppend('section', main, {
- class: 'repo-container whiteframe',
- });
- const contributors = createAndAppend('section', main, {
- class: 'contributors-container whiteframe',
- });
- return { header, error, main, repo, contributors };
- }
- }
-
- const ACCOUNT_KEY = 'hyf';
- window.onload = () => new App(accounts[ACCOUNT_KEY]);
-}
diff --git a/homework-classes/ContributorsView.js b/homework-classes/ContributorsView.js
deleted file mode 100755
index 58cb2b984..000000000
--- a/homework-classes/ContributorsView.js
+++ /dev/null
@@ -1,28 +0,0 @@
-'use strict';
-
-{
- const { createAndAppend } = window.Util;
-
- class ContributorsView {
- constructor(container) {
- this.container = container;
- }
-
- update(state) {
- if (!state.error) {
- this.render(state.contributors);
- }
- }
-
- /**
- * Renders the list of contributors
- * @param {Object[]} contributors An array of contributor objects
- */
- render(contributors) {
- // TODO: replace this comment and the console.log with your own code
- console.log('ContributorsView', contributors);
- }
- }
-
- window.ContributorsView = ContributorsView;
-}
diff --git a/homework-classes/ErrorView.js b/homework-classes/ErrorView.js
deleted file mode 100755
index 67ad53087..000000000
--- a/homework-classes/ErrorView.js
+++ /dev/null
@@ -1,31 +0,0 @@
-'use strict';
-
-{
- const { createAndAppend } = window.Util;
-
- class ErrorView {
- constructor(container) {
- this.container = container;
- }
-
- update(state) {
- this.render(state.error);
- }
-
- /**
- * Renders an error for the 'error' message type.
- * @param {Error} error An Error object
- */
- render(error) {
- this.container.innerHTML = '';
- if (error) {
- createAndAppend('div', this.container, {
- text: error.message,
- class: 'alert alert-error',
- });
- }
- }
- }
-
- window.ErrorView = ErrorView;
-}
diff --git a/homework-classes/HeaderView.js b/homework-classes/HeaderView.js
deleted file mode 100755
index 11f9c8971..000000000
--- a/homework-classes/HeaderView.js
+++ /dev/null
@@ -1,46 +0,0 @@
-'use strict';
-
-{
- const { createAndAppend } = window.Util;
-
- class HeaderView {
- constructor(account, header, fetchData) {
- this.account = account;
- this.header = header;
- this.fetchData = fetchData;
- this.select = null;
- }
-
- update(state) {
- if (!this.select && !state.error) {
- this.render(state.repos);
- }
- }
-
- /**
- * Renders the data for the 'select' message type. Create a element
- * and its children.
- * @param {Object[]} repos An array of repository objects.
- */
- render(repos) {
- createAndAppend('div', this.header, { text: this.account.name });
- this.select = createAndAppend('select', this.header, {
- class: 'repo-select',
- autofocus: 'autofocus',
- });
-
- repos.forEach(repo =>
- createAndAppend('option', this.select, {
- text: repo.name,
- value: repo.id,
- }),
- );
-
- this.select.addEventListener('change', () =>
- this.fetchData(this.select.value),
- );
- }
- }
-
- window.HeaderView = HeaderView;
-}
diff --git a/homework-classes/Model.js b/homework-classes/Model.js
deleted file mode 100755
index 25884a133..000000000
--- a/homework-classes/Model.js
+++ /dev/null
@@ -1,53 +0,0 @@
-'use strict';
-
-{
- const { Observable } = window;
-
- const makeUrl = ({ name, type }) =>
- `https://api.github.com/${type}s/${name}/repos?per_page=100`;
-
- class Model extends Observable {
- constructor(account) {
- super();
- this.account = account;
- this.state = {
- repos: [],
- selectedRepo: null,
- contributors: [],
- error: null,
- };
- }
-
- async fetchData(id) {
- const repoId = parseInt(id, 10);
- this.state.error = null;
- try {
- if (this.state.repos.length === 0) {
- const repos = await Model.fetchJSON(makeUrl(this.account));
- this.state.repos = repos.sort((a, b) => a.name.localeCompare(b.name));
- }
- const index = id
- ? this.state.repos.findIndex(repo => repo.id === repoId)
- : 0;
- this.state.selectedRepo = this.state.repos[index];
- this.state.contributors = await Model.fetchJSON(
- this.state.selectedRepo.contributors_url,
- );
- } catch (err) {
- this.state.error = err;
- }
- this.notify(this.state);
- }
-
- static fetchJSON(url) {
- return fetch(url).then(res => {
- if (!res.ok) {
- return new Error(`HTTP ${res.status} - ${res.statusText}`);
- }
- return res.status === 200 ? res.json() : null;
- });
- }
- }
-
- window.Model = Model;
-}
diff --git a/homework-classes/Observable.js b/homework-classes/Observable.js
deleted file mode 100755
index 3eb5b2530..000000000
--- a/homework-classes/Observable.js
+++ /dev/null
@@ -1,20 +0,0 @@
-'use strict';
-
-{
- class Observable {
- constructor() {
- this.observers = new Set();
- }
-
- subscribe(observer = {}) {
- this.observers.add(observer);
- return () => this.observers.delete(observer);
- }
-
- notify(data) {
- this.observers.forEach(observer => observer.update(data));
- }
- }
-
- window.Observable = Observable;
-}
diff --git a/homework-classes/RepoView.js b/homework-classes/RepoView.js
deleted file mode 100755
index 073166fea..000000000
--- a/homework-classes/RepoView.js
+++ /dev/null
@@ -1,28 +0,0 @@
-'use strict';
-
-{
- const { createAndAppend } = window.Util;
-
- class RepoView {
- constructor(container) {
- this.container = container;
- }
-
- update(state) {
- if (!state.error) {
- this.render(state.selectedRepo);
- }
- }
-
- /**
- * Renders the repository details.
- * @param {Object} repo A repository object.
- */
- render(repo) {
- // TODO: replace this comment and the console.log with your own code
- console.log('RepoView', repo);
- }
- }
-
- window.RepoView = RepoView;
-}
diff --git a/homework-classes/Util.js b/homework-classes/Util.js
deleted file mode 100755
index dc5d79a87..000000000
--- a/homework-classes/Util.js
+++ /dev/null
@@ -1,27 +0,0 @@
-'use strict';
-
-{
- class Util {
- /**
- * Creates an element, optionally setting its attributes, and appends
- * the element to a parent.
- * @param {string} name The tag name of the element to create.
- * @param {HTMLElement} parent The parent element.
- * @param {Object} options An object with attribute names and values.
- */
- static createAndAppend(name, parent, options = {}) {
- const elem = document.createElement(name);
- parent.appendChild(elem);
- Object.entries(options).forEach(([key, value]) => {
- if (key === 'text') {
- elem.textContent = value;
- } else {
- elem.setAttribute(key, value);
- }
- });
- return elem;
- }
- }
-
- window.Util = Util;
-}
diff --git a/homework-classes/style.css b/homework-classes/style.css
deleted file mode 100755
index 90d106051..000000000
--- a/homework-classes/style.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.alert-error {
- color: red;
-}
diff --git a/homework/hyf.png b/homework/hyf.png
deleted file mode 100755
index 76bc5a13b..000000000
Binary files a/homework/hyf.png and /dev/null differ
diff --git a/homework/index.html b/homework/index.html
deleted file mode 100755
index 9c8f80c1a..000000000
--- a/homework/index.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- Codestin Search App
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/homework/index.js b/homework/index.js
deleted file mode 100755
index 3886cbac9..000000000
--- a/homework/index.js
+++ /dev/null
@@ -1,54 +0,0 @@
-'use strict';
-
-{
- function fetchJSON(url, cb) {
- const xhr = new XMLHttpRequest();
- xhr.open('GET', url);
- xhr.responseType = 'json';
- xhr.onload = () => {
- if (xhr.status >= 200 && xhr.status <= 299) {
- cb(null, xhr.response);
- } else {
- cb(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`));
- }
- };
- xhr.onerror = () => cb(new Error('Network request failed'));
- xhr.send();
- }
-
- function createAndAppend(name, parent, options = {}) {
- const elem = document.createElement(name);
- parent.appendChild(elem);
- Object.entries(options).forEach(([key, value]) => {
- if (key === 'text') {
- elem.textContent = value;
- } else {
- elem.setAttribute(key, value);
- }
- });
- return elem;
- }
-
- function renderRepoDetails(repo, ul) {
- createAndAppend('li', ul, { text: repo.name });
- }
-
- function main(url) {
- fetchJSON(url, (err, repos) => {
- const root = document.getElementById('root');
- if (err) {
- createAndAppend('div', root, {
- text: err.message,
- class: 'alert-error',
- });
- return;
- }
- const ul = createAndAppend('ul', root);
- repos.forEach(repo => renderRepoDetails(repo, ul));
- });
- }
-
- const HYF_REPOS_URL =
- 'https://api.github.com/orgs/HackYourFuture/repos?per_page=100';
- window.onload = () => main(HYF_REPOS_URL);
-}
diff --git a/homework/style.css b/homework/style.css
deleted file mode 100755
index 90d106051..000000000
--- a/homework/style.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.alert-error {
- color: red;
-}
diff --git a/package-lock.json b/package-lock.json
index 7ccbb2e22..0d74aedda 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1016,9 +1016,9 @@
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
},
"prettier": {
- "version": "1.18.2",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz",
- "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw=="
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
+ "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew=="
},
"prettier-linter-helpers": {
"version": "1.0.0",
diff --git a/package.json b/package.json
index a3233dcca..685329c36 100755
--- a/package.json
+++ b/package.json
@@ -15,6 +15,6 @@
"eslint-config-prettier": "^6.0.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-prettier": "^3.1.0",
- "prettier": "^1.18.2"
+ "prettier": "^1.19.1"
}
}
diff --git a/test.md b/test.md
index 49ce67e2c..168ba207d 100644
--- a/test.md
+++ b/test.md
@@ -29,7 +29,7 @@ The test will be about all main JavaScript concepts we have discussed for the pa
- `Array functions`
- `Conditional statements`
- `DOM manipulations`
-- `Fetch & API calls`
+- `Fetch & HTTP Requests`
- `Promises & Async/await`
- `Try…catch`
@@ -60,7 +60,7 @@ Advise on how to make a test:
1. Using JavaScript only (adding HTML to index.html is NOT allowed), create a button element (with text "click me!") and an empty image element and add it to the document. When the button is clicked, insert an image URL into the tag and remove the button. Use the following image URL: https://thehub.dk/files/5ad4b4a9f9ac4aa13c3d2d58/logo_upload-6d537cf7e5de664db275b32b3c6ae12d.png
-2. Make an API call using the Fetch API or the regular XMLHttpRequest (whichever one you're more comfortable with). Use the following API: https://reqres.in/api/users
+2. Make a HTTP Request using the Fetch API or the regular XMLHttpRequest (whichever one you're more comfortable with). Use the following API: https://reqres.in/api/users
Parse the response and then display the "first_name" and "last_name" of the first three users within the DOM (inside an unordered list)
If there’s anything unclear please let us know. Also, if any of you need additional support, now is the moment to let us know as we could pair you up with someone to answer any questions you may have.