Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
- [Week 3](courses/frontend/advanced-javascript/week3/README.md)
- [Preparation](courses/frontend/advanced-javascript/week3/preparation.md)
- [Session Plan](courses/frontend/advanced-javascript/week3/session-plan.md)
- [Exercises](courses/frontend/advanced-javascript/week3/session-materials/exercises.md)
- [Assignment](courses/frontend/advanced-javascript/week3/assignment.md)
- [Week 4](courses/frontend/advanced-javascript/week4/README.md)
- [Preparation](courses/frontend/advanced-javascript/week4/preparation.md)
Expand Down
12 changes: 6 additions & 6 deletions courses/frontend/advanced-javascript/week2/assignment.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,25 @@ The warmup is a **little abstract**, it will get more concrete later on!
1. Display the text `Called after 2.5 seconds` on the page 2.5 seconds after the script is loaded.

2. Create a function that takes 2 parameters: `delay` and `stringToLog`. Calling this function should display the `stringToLog` on the page after `delay` seconds. Call the function you have created with some different arguments.
![second task](session-materials/carbon.png)
![second task](./session-materials/carbon.png)

3. Create a button in html. When clicking this button, use the function you created in the previous task to display the text `Called after 5 seconds` on the page 5 seconds after the button is clicked.

![second task](session-materials/button-delay.gif)
![second task](./session-materials/button-delay.gif)

4. Create two functions and assign them to two different variables. One function displays `Earth` on the page, the other displays `Saturn`. Now create a new third function that has one parameter: `planetLogFunction`. The only thing the third function should do is call the provided parameter function. Try calling the third function once with the `Earth` function and once with the `Saturn` function.

![second task](session-materials/planet-log.png)
![second task](./session-materials/planet-log.png)

5. Create a button with the text "Log location". When this button is clicked, display the user's location (latitude, longitude) on the page using this [browser API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API).

![second task](session-materials/log-location.gif)
![second task](./session-materials/log-location.gif)

6. _Optional_ Now show that location on a map using e.g. the [Google maps api](https://developers.google.com/maps/documentation/javascript/tutorial)

7. Create a function called `runAfterDelay`. It has two parameters: `delay` and `callback`. When called the function should wait `delay` seconds and then call the provided callback function. Add an input in the HTML for the delay (in seconds) and a button; when the button is clicked, read the delay from the input and call `runAfterDelay` with that delay and a callback that displays something on the page.

![second task](session-materials/run-after-delay.png)
![second task](./session-materials/run-after-delay.png)

8. Check if the user has double-clicked on the page. A double click is two clicks within 0.5 seconds. If a double click is detected, display the text "double click!" on the page.

Expand Down Expand Up @@ -57,7 +57,7 @@ A user specifies how long time the game should be, and presses **"start game!"**

Here is a gif of how the site should work:

![session material](session-materials/fastest-clicker.gif =400x)
![Fastest presser game demo](./session-materials/fastest-clicker.gif)

You can implement it exactly like you want to, but here is my recommended order:

Expand Down
1 change: 1 addition & 0 deletions courses/frontend/advanced-javascript/week3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ In this session, you'll learn how to write asynchronous code that is both effici

- [Preparation](./preparation.md)
- [Session Plan](./session-plan.md) (for mentors)
- [Exercises](./session-materials/exercises.md)
- [Assignment](./assignment.md)

## Session Learning Goals
Expand Down
14 changes: 8 additions & 6 deletions courses/frontend/advanced-javascript/week3/assignment.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# Assignment

The assignment for this week is to build a currency calculator using [this API](https://open.er-api.com/v6/latest/USD)
The assignment for this week is to build a currency calculator using [this API](https://open.er-api.com/v6/latest/USD).

Deliverable: a small browser application, so the user can interact with it and see the converted amount on the page.

## Technical specifications

1. Make a request to the API and store the Exchange rates as well as a list of currencies for the dropdowns.
2. User can enter an amount
3. User can choose a currency to convert from(default should be EUR)
4. User can choose a currency to convert to(Default should be DKK)
5. Whenever amount, currency from or currency to changes we show what the amount translates to in the to currency
1. Make a request to the API and use the response to obtain exchange rates and to populate the currency dropdowns.
2. The user can enter an amount.
3. The user can choose a currency to convert from (default: EUR).
4. The user can choose a currency to convert to (default: DKK).
5. When the amount, the "from" currency, or the "to" currency changes, show the equivalent amount in the "to" currency.
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Promise chaining – what is logged?

Use these in class: show the code, ask “What will appear in the console, and in what order?”, then run it and compare.

---

## Task 1 — basic: sync vs `.then`

```js
console.log("A");

Promise.resolve().then(() => {
console.log("B");
});

console.log("C");
```

<details>
<summary>Answer</summary>

Order: A, C, B

Synchronous code runs first (A, then C). Callbacks passed to `.then` are scheduled as microtasks and run after the current script finishes, so B appears last.

</details>

---

## Task 2 — values through the chain

```js
Promise.resolve(1)
.then((x) => {
console.log(x);
return x + 1;
})
.then((y) => {
console.log(y);
});
```

<details>
<summary>Answer</summary>

Logs: `1` then `2`

Each `.then` receives the value returned by the previous handler. Returning a plain value wraps it in a resolved promise for the next step.

</details>

---

## Task 3 — returning a Promise (flattening)

```js
Promise.resolve("go")
.then((s) => {
console.log("a:", s);
return Promise.resolve("step");
})
.then((t) => {
console.log("b:", t);
});
```

<details>
<summary>Answer</summary>

Logs: `a: go` then `b: step`

When a handler returns a Promise, the chain waits for it and passes its settled value to the next `.then` (the inner Promise is “flattened”).

</details>

---

## Task 4 — rejection, skipped handlers, `.catch`, recovery

```js
Promise.resolve()
.then(() => {
console.log("1");
throw new Error("oops");
})
.then(() => {
console.log("2");
})
.catch(() => {
console.log("3");
})
.then(() => {
console.log("4");
});
```

<details>
<summary>Answer</summary>

Logs: `1`, `3`, `4`

The error skips the next `.then` (so `2` never runs). `.catch` handles the rejection; a successful `catch` returns a fulfilled promise, so the following `.then` still runs (`4`).

</details>

---

## Task 5 — multiple `.catch` and `.then` in one chain

```js
Promise.resolve()
.then(() => {
console.log("1");
throw "first-error";
})
.catch((err) => {
console.log("catch-A", err);
return "recovered";
})
.then((value) => {
console.log("2", value);
throw "second-error";
})
.catch((err) => {
console.log("catch-B", err);
})
.then(() => {
console.log("3");
});
```

<details>
<summary>Answer</summary>

Logs: `1`, `catch-A first-error`, `2 recovered`, `catch-B second-error`, `3`

The first `throw` is handled by `catch-A`, which returns `"recovered"`, so the chain continues fulfilled and `2` runs with that value. The next `throw` is handled by `catch-B`; a successful `catch` still yields a fulfilled promise, so the final `.then` runs (`3`). The second `.catch` never sees `first-error` because `catch-A` already handled it.

</details>
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Mentors demo – Promises & `async`/`await`

In-session live coding for **Week 3** (Advanced JavaScript). The demo walks through `fetch` with **JSONPlaceholder**, `async`/`await`, consuming promises with `.then()` / `.catch()`, creating promises with `new Promise`, `try` / `catch` with async code, `Promise.all`, and an optional promise microtask loop. You implement the worksheet during class; the solution file is the finished version.

---

## Files in this folder

| File | Purpose |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **index.js** | Worksheet: section banners, `// Task:` lines, and `// Next:` hints. Only `getUser` and `promiseLoop` are declared; you add the rest while teaching. Use this file when leading the session. |
| **index-solution.js** | Full implementation: `showOutput`, `getUser`, promise consumption, timed and pizza promises, `try` / `catch` fetch, `Promise.all`, and `promiseLoop`. |
| **index.html** | Minimal page that loads `index.js`. Add markup (e.g. `<pre id="out">`) when you want on-page output; the solution’s `showOutput` writes to `#out`. |
| **style.css** | Basic layout and styles for `#out` (and `main` if you use it). |

---

## Where to find tasks and how they are marked

Everything lives in **index.js**. Search for `// ==========` for section breaks, `// Task:` for what to build, and `// Next:` for suggested links to the trainee exercises.

---

## How the code works

### URLs (JSONPlaceholder)

- **`USER_URL`** – `https://jsonplaceholder.typicode.com/users/1`
- **`POST_URL`** – `https://jsonplaceholder.typicode.com/posts/1`
- **`TODO_URL`** – `https://jsonplaceholder.typicode.com/todos/1` (optional extra)

### Solution-only helpers and functions

- **`showOutput(text)`** – Sets `textContent` on `#out` when that element exists.
- **`getUser()`** – `async` `fetch` of **`USER_URL`**, then `.json()`, then `showOutput` with stringified user data.
- **`loadOneResourceWithThen()`** – Same resource with `.then` / `.catch` only (no `async`/`await`).
- **`oneSecondMessage()`** – Promise that resolves after one second, then shows `"It worked"`.
- **`demoOrderPizza()`** – Delayed resolve or reject, then shows pizza or error text.
- **`getUserWithTryCatch()`** – Same fetch pattern as `getUser` with `try` / `catch` and errors on the page.
- **`demoPromiseAll()`** – Fetches **`USER_URL`** and **`POST_URL`** in parallel, then shows a short two-line summary.
- **`promiseLoop()`** – Schedules endless microtasks (illustration only; can freeze the tab if called).

### Callback hell

Not implemented in these files; use the session plan (e.g. npm `q` or your own example on the board).
Loading
Loading