Skip to content
Merged
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
2 changes: 2 additions & 0 deletions courses/frontend/advanced-javascript/week1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ This session is about mastering the most commonly used array functions provided

Understanding how to use array functions and the arrow notation can greatly improve the readability of your code.

The module strongly encourages going beyond JavaScript alone and **implementing a real frontend**—work that runs in the browser with a visible, interactive UI. All exercises (session materials and assignment) are designed so that JavaScript drives HTML and the interface.

## Contents

- [Preparation](./preparation.md)
Expand Down
15 changes: 9 additions & 6 deletions courses/frontend/advanced-javascript/week1/assignment.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Assignment

<!-- The type of assignment you write will vary a lot depending on the module. But either way, all of the set up, instructions and tips should be captured in here. -->
Tasks 1 and 2 are short warmups; task 3 is a larger, real-world-style task where everything is visible in one page or app.

The warmup exercises will be a bit abstract. But the in the **hyfBay exercise** the task will be a lot closer to a **real world task**.
- **Task 1 (Doubling of number):** JavaScript only. Submit your solution using `map` and `filter` (and arrow functions).
- **Task 2 (Codewars):** Complete the Katas on Codewars. No frontend or repo submission needed.
- **Task 3 (Working with movies):** Frontend required. Build an HTML page with CSS and JavaScript that runs in the browser and shows the result of each movie sub-task in the page (e.g. sections or cards with the computed data).

## 1. Doubling of number

Expand All @@ -19,11 +21,10 @@ for (let i = 0; i < numbers.length; i++) {
newNumbers[i] = numbers[i] * 2;
}
}

console.log("The doubled numbers are", newNumbers); // [2, 6]
// expected result: [2, 6]
```

Rewrite the above program using `map` and `filter` don't forget to use arrow functions.
Rewrite the above program using `map` and `filter`; don't forget to use arrow functions.

## 2. Codewars!

Expand All @@ -36,7 +37,9 @@ Complete these Katas:

![cinema](https://media.giphy.com/media/l6mBchxYZc7Sw/giphy.gif)

Copy the movies array in the [movies](./session-materials/movies.js) file. Use this array to do the following tasks:
**What the user sees:** One page (e.g. sections or cards) where every sub-task’s result is visible in the browser: short titles, long titles, 1980s count, tagged movies, ratings over 6, keyword count, duplicated-word titles, and optionally average rating and Good/Average/Bad counts.

Copy the movies array from [movies](./session-materials/movies.js) and use it for the tasks below.

1. Create an array of movies containing the **movies with a short title** (you define what short means)
2. Create an array of movie titles with **long movie titles**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,58 +1,54 @@
# Exercises

Use [generateListings()](./code-inspiration.md#generatelistings) to generate random listings
Work in the [Listings demo](https://github.com/HackYourFuture-CPH/hyf-assignment-template/blob/main/courses/frontend/advanced-javascript/week1/listings-demo). Open **index.html** in your browser to run the demo, and open **index.js** in your IDE to implement the tasks. In `index.js`, search for **`Task`** (e.g. Task 1.1, Task 2)—each task has a comment with explicit instructions about what code to write. This document describes the **end-result** you’re aiming for and how the exercise is set up. The generation of random listings and the render helpers (cards, price list) are already implemented; you only need to call them and add the logic that uses `.forEach()`, `.map()`, and `.filter()`.

## `forEach`
## Task 1: Generate and show listings (`forEach`)

- Create 37 listings and log out every listing's size
**What should happen:** When the user clicks **Generate listings (37) — Task 1**, 37 random listings are generated and displayed as cards on the page.

## `map`
**Listing** (each object in the generated array):

- Create an array that contains all the 37 listing prices.
| Property | Type | Description |
| ------------ | -------- | ----------------------------------------------------------- |
| `type` | string | e.g. `"House"`, `"Apartment"`, `"Shed"`, `"Dorm"`, `"Farm"` |
| `facilities` | string[] | e.g. `["Parkering", "Have"]` |
| `price` | number | 1–10000 |
| `hasGarden` | boolean | |
| `size` | number | m², 12–1000 |
| `img` | string | image URL |

## `filter`
You implement the logic that (1) triggers generation and (2) renders the listings by iterating over the array and adding one card per listing. The code that builds each card and prepares the view is already there; you use `listings.forEach(...)` to show every listing.

Using the 37 listings from the previous tasks,
## Task 2: Show prices (`map`)

- Create an array of cheap listings. You define what "cheap" means. Each item in this array should be of type `object`
- Create an array of expensive listings' prices. Each item in this array should be of type `number`
- Create an array of listings that have parking. Each item in this array should be of type `object`
**What should happen:** After generating listings, when the user clicks **Show prices — Task 2**, a list of all listing prices appears (e.g. comma-separated) in the prices area.

## Arrow functions
You implement getting an array of prices from the current listings and passing it to the helper that displays numbers. Use `.map()` to turn the list of listings into a list of prices.

Rewrite the code above (`forEach`, `map` and `filter`) to arrow functions.
## Task 3: Filter buttons (`filter`)

## Listing project
**What should happen:** When the user clicks one of the filter buttons, the page shows only the matching listings (or their prices).

Imagine we have a website like [Danske Bank](https://danskebank.dk/bolig/sogning/liste?sorter=hoejt-forbrug) where a user can search for different parameters. For example: what type the listing should be, the price, size, location etc etc.
- **Cheap listings — Task 3a:** Only “cheap” listings are shown as cards. You decide what “cheap” means (e.g. price below a certain number). Use `.filter()` and then the same render-as-cards logic as in Task 1.
- **Expensive prices — Task 3b:** Only the _prices_ of “expensive” listings are shown (as numbers). Use `.filter()` to get expensive listings, then `.map()` to get their prices, and the helper that displays numbers.
- **With parking — Task 3c:** Only listings that have “Parkering” in their facilities are shown as cards. Use `.filter()` on the facilities.

### Filter the listings
## Task: Arrow functions

Image that a user clicks on a button indicating that they only want listings that are of the type "farm". Let's try and imagine how we would use a function to create this functionality:
Rewrite the code you wrote for Tasks 1–3 to use arrow function syntax instead of `function`.

```js
const listings = generateListings(20);
## Task 4: Advanced filters (Listing project)

const filter = {
type: "farm",
};
**What should happen:** The user can set type, min price, min size, facilities, and garden in the Advanced filters form. When they click **Apply filters — Task 4**, only listings that match _all_ selected criteria are shown as cards.

const farmListings = filterListings(listings, filter);
```
You implement **filterListings(listings, filter)**. Reading the form and building the `filter` object is already done; you receive an object with only the fields the user set. Return only listings that match every property present in `filter`. If a property is missing from `filter`, don’t filter by it.

Okay, so the `filterListings` function takes a filter which is an `object`. Say the user wants "farm" listings that cost more than 1.5 million.
**Filter** (object passed to `filterListings`; only set fields are present):

```js
const filter2 = {
type: "farm",
minPrice: 1500000,
};

const expensiveFarmListings = filterListings(listings, filter2);
```

Your job is to create the `filterListings` function. The function should support these filters: type, facilities, minPrice, hasGarden and size. Use arrow functions!

### Render the listings

Now create a function called `renderListings`. It should have one parameter: `listings`. When called, the function should render the listings in an html list. How it should be rendered is up to you, but you could take inspiration from [Danske Bank](https://danskebank.dk/bolig/sogning?sorter=hoejt-forbrug)
| Property | Type | Meaning |
| ------------ | -------- | ------------------------------------------------------------- |
| `type` | string | `listing.type` must equal this. |
| `minPrice` | number | `listing.price` must be ≥ this. |
| `minSize` | number | `listing.size` must be ≥ this (m²). |
| `hasGarden` | boolean | If `true`, `listing.hasGarden` must be `true`. |
| `facilities` | string[] | `listing.facilities` must include every string in this array. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Mentors demo – forEach, map, filter

In-session demo for **Week 1** (Advanced JavaScript). A fixed list of mentors is shown in the page; four buttons run different array operations (forEach, map, filter, and chained filter). All output is rendered in the page. The goal is to implement the missing parts during the session using the normal array methods (`.forEach()`, `.map()`, `.filter()`), and to implement the "homemade" versions for demonstration.

---

## Files in this folder

| File | Purpose |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **index.js** | Worksheet for **implementing in class**. Contains data, render helpers, and stubs. Missing logic is marked with `// {TOPIC} TODO:` comments. Use this file when leading the session. |
| **index-solution.js** | Final implementation. |
| **index.html** | Page layout: four action buttons and a result area. Load this in a browser to run the demo. No edits needed. |
| **style.css** | Styles for cards, buttons, and layout. No edits needed. |

---

## Where to find tasks and how they are marked

All tasks are in **index.js**. They are marked with **TODO** comments so you can search for `TODO` in the file.

- **FOREACH TODO** – Implement the homemade `forEach` (demonstration only) and/or the logic in `renderCards` that shows all mentors as cards (using `.forEach()`).
- **MAP TODO** – Implement the homemade `map` (demonstration only) and/or the logic in `showNamesOnly` that builds an array of mentor names and passes it to `renderNamesList` (using `.map()`).
- **FILTER TODO** – Implement the homemade `filter` (demonstration only) and/or the logic in `showExperienced` that keeps only mentors with `yearOfExperience > 7` (using `.filter()`).
- **CHAINING TODO** – In `showNamesStartingWithA`, implement filtering with multiple conditions (e.g. name starts with `"A"` and `yearOfExperience > 2`), using chained `.filter()` or a single `.filter()` with both conditions.

---

## How the code works

### Main HTML elements (index.html)

- **`.actions`** – Wrapper around the four buttons. Each button calls `setActive(this)` and one of: `showAllMentors()`, `showNamesOnly()`, `showExperienced()`, `showNamesStartingWithA()`.
- **`#resultLabel`** – Text that describes the current result (e.g. “Result: forEach – all mentors”).
- **`#result`** – Container where the output is rendered: either a grid of mentor cards or a comma-separated list of names.

### Main render functions (index.js)

- **`renderMentorCard(mentor)`** – Creates one card element for a mentor: name, years of experience, and subjects (using `.map()` on `mentor.subjects`). Returns a `div.card`; does **not** append it to the page.
- **`renderNamesList(names)`** – Clears `#result`, then shows the `names` array as comma-separated text in a single element. If `names` is empty, shows `"No names."`.
- **`renderCards(mentorsToShow)`** – Clears `#result`, creates a wrapper `div.cards`, then should append one card per mentor by calling `renderMentorCard(mentor)` for each and appending to the wrapper. The wrapper is then appended to `#result`. This is the **forEach** example: use `mentorsToShow.forEach(...)` to add every card.
- **`setActive(clickedBtn)`** – Removes the `active` class from all `.actions` buttons and adds it to the clicked button (for styling the selected action).

### Data and demo flow

- **`mentors`** – Array of mentor objects, each with `name`, `subjects` (array of strings), and `yearOfExperience` (number).
- **Demo actions** – `showAllMentors()`, `showNamesOnly()`, `showExperienced()`, `showNamesStartingWithA()`. See the code for what each does.

On load, `showAllMentors()` runs so the page initially shows all mentors as cards.
Loading