diff --git a/curriculum/challenges/english/blocks/lab-fcc-forum-leaderboard/673c91f0b934834bc4a3ecc2.md b/curriculum/challenges/english/blocks/lab-fcc-forum-leaderboard/673c91f0b934834bc4a3ecc2.md index 2ae1e39bb61..b491b53b14f 100644 --- a/curriculum/challenges/english/blocks/lab-fcc-forum-leaderboard/673c91f0b934834bc4a3ecc2.md +++ b/curriculum/challenges/english/blocks/lab-fcc-forum-leaderboard/673c91f0b934834bc4a3ecc2.md @@ -10,6 +10,46 @@ demoType: onClick In this lab, you will build a freeCodeCamp forum leaderboard that displays the latest topics, users, and replies from the [freeCodeCamp forum](https://forum.freecodecamp.org/). The HTML, CSS and part of the JS have been provided for you. Feel free to explore them. +The API endpoint returns JSON in the following shape: + +```json +{ + "users": [ + { + "id": 6, + "username": "QuincyLarson", + "name": "Quincy Larson", + "avatar_template": "/user_avatar/QuincyLarson_{size}.png" + }, + { + "id": 576147, + "username": "JOY-OKORO", + "name": "Joy Okoro", + "avatar_template": "/user_avatar/JOY-OKORO_{size}.png" + } + ], + "topic_list": { + "topics": [ + { + "id": 684569, + "title": "The freeCodeCamp Podcast is back – now with video", + "slug": "the-freecodecamp-podcast-is-back-now-with-video", + "posts_count": 8, + "views": 542, + "bumped_at": "2024-04-15T16:01:26.403Z", + "category_id": 1, + "posters": [ + { "user_id": 6 }, + { "user_id": 576147 } + ] + } + ] + } +} +``` + +Note that `avatar_template` values are relative paths: they start with `/` and contain a `{size}` placeholder that should be replaced with a pixel size. The `avatarUrl` constant holds the base URL to prepend when the path is relative. + **Objective:** Fulfill the user stories below and get all the tests to pass to complete the lab. **User Stories:** @@ -25,13 +65,13 @@ In this lab, you will build a freeCodeCamp forum leaderboard that displays the l 1. The `forumCategory` function should verify that the selected category id is a property of the `allCategories` object and should return a string containing an anchor element with: - the text of the `category` key of the selected category. - a class of `category` followed by the `className` property of the selected category. - - an `href` with the value of `//`, where `` is the `className` property of the selected category and `id` is the argument passed to `forumCategory`. + - an `href` formed by appending `/` to `forumCategoryUrl` (note: `forumCategoryUrl` already ends with `/`, so do not add an extra `/` separator), where `` is the `className` property of the selected category and `id` is the argument passed to `forumCategory`. 1. If the `allCategories` object does not have the selected category id as its property, `category` should be indicated as `General` and `className` should be indicated as `general`. 1. You should have a function named `avatars` that takes two arrays representing posters and users, respectively. 1. The `avatars` function should return a string made by joining `img` elements, one for each `user_id` in the `posters` array. Find the `img` URL by looking up the `user_id` property in the `posters` array and find the matching `id` property in the `users` array. -1. The `avatars` function should set each avatar's size by accessing the `avatar_template` property and replacing `{size}` with `30`. +1. The `avatars` function should set each avatar's size by accessing the `avatar_template` property of the matched user object (found in the `users` array by comparing its `id` to the `user_id` in `posters`) and replacing the `{size}` placeholder in the URL string with `30`. 1. Each image element should have an alt text with the value of the `name` property of the poster. -1. Each image element should have a source with the value of the `avatar_template` property of the poster. In case `avatar_template` contains a relative path, you should set the source to `/`. +1. Each `img` element should have a `src` attribute set to the `avatar_template` of the matched user. If `avatar_template` starts with `/`, prepend `avatarUrl` directly to it. 1. You should have a function named `showLatestPosts` that takes a single parameter. 1. The `showLatestPosts` should extract the `users` and `topic_list` properties from the object passed as argument. Also, it should process the following properties of the objects from the `topics` array, which is contained in `topic_list`: - `id`: the id of the post @@ -182,11 +222,11 @@ assert.lengthOf(forumCategory, 1); ```js let actual = forumCategory(299); -assert.match(actual, /^<\s*a.+?>\s*Career Advice\s*<\/a>$/); +assert.match(actual.trim(), /^<\s*a.+?>\s*Career Advice\s*<\/a>$/); // prevent hardcoding actual = forumCategory(409); -assert.match(actual, /^<\s*a.+?>\s*Project Feedback\s*<\/a>$/); +assert.match(actual.trim(), /^<\s*a.+?>\s*Project Feedback\s*<\/a>$/); ``` `forumCategory(299)` should return a string containing an anchor element with `href="https://forum.freecodecamp.org/c/career/299"`. @@ -221,7 +261,7 @@ assert.match(actual, /class=("|')category\s+feedback\1/); ```js const actual = forumCategory(200); -assert.match(actual, /^<\s*a.+?>\s*General\s*<\/a>$/); +assert.match(actual.trim(), /^<\s*a.+?>\s*General\s*<\/a>$/); ``` `forumCategory(200)` should return a string containing an anchor element with `href="https://forum.freecodecamp.org/c/general/200"`. @@ -356,7 +396,7 @@ assert.notMatch(actual, /\{size\}/); assert.lengthOf(actual.match(/_30/g), 3); ``` -Each `img` element in the string returned by the `avatars` function should have the `src` with the value of the `avatar_template` property of the poster. In case `avatar_template` contains a relative path, it should be set to `/`. +Each `img` element should have a `src` attribute set to the `avatar_template` of the matched user. If `avatar_template` starts with `/`, prepend `avatarUrl` directly to it. ```js const posters = [{ user_id: 6 }, { user_id: 285941 }, { user_id: 170865 }];