Tell us what’s happening:
Hello,
For me, all tests passes except for test 33. And I have no clue, why? There are console errors. I am unable to pinpoint the issue, please help.
Thanks
Your code so far
<!-- file: index.html -->
/* file: styles.css */
/* file: script.js */
Your browser information:
User Agent is: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36
Challenge Information:
Build an fCC Forum Leaderboard - Build an fCC Forum Leaderboard
https://www.freecodecamp.org/learn/full-stack-developer/lab-fcc-forum-leaderboard/build-an-fcc-forum-leaderboard
below is my solution:-
const forumLatest =
"https://cdn.freecodecamp.org/curriculum/forum-latest/latest.json";
const forumTopicUrl = "https://forum.freecodecamp.org/t/";
const forumCategoryUrl = "https://forum.freecodecamp.org/c/";
const avatarUrl = "https://sea1.discourse-cdn.com/freecodecamp";
const allCategories = {
299: { category: "Career Advice", className: "career" },
409: { category: "Project Feedback", className: "feedback" },
417: { category: "freeCodeCamp Support", className: "support" },
421: { category: "JavaScript", className: "javascript" },
423: { category: "HTML - CSS", className: "html-css" },
424: { category: "Python", className: "python" },
432: { category: "You Can Do This!", className: "motivation" },
560: { category: "Backend Development", className: "backend" },
};
function timeAgo(isoTimestamp) {
const diffInMs = new Date() - new Date(isoTimestamp);
const diffInMins = Math.floor(diffInMs / (1000 * 60));
if (diffInMins < 60) {
return `${diffInMins}m ago`;
}
const diffInHours = Math.floor(diffInMins / 60);
if (diffInHours < 24) {
return `${diffInHours}h ago`;
}
const diffInDays = Math.floor(diffInHours / 24);
return `${diffInDays}d ago`;
}
//console.log(new Date().toISOString());
//console.log(timeAgo("2025-03-23T12:00:00Z")); // Output depends on current time
const viewCount = (numViews) => {
return numViews >= 1000 ? `${Math.floor(numViews / 1000)}k` : numViews;
};
const forumCategory = (id) => {
if (allCategories.hasOwnProperty(id)) {
return `<a class="category ${allCategories[id].className}" href="${forumCategoryUrl}${allCategories[id].className}/${id}">${allCategories[id].category}</a>`;
} else {
return `<a class="category general" href="${forumCategoryUrl}general/${id}">General</a>`;
}
};
//console.log(forumCategory("299"));
const avatars = (posters, users) => {
let img = "";
users
.filter((user) => posters.some((poster) => poster.user_id === user.id))
.forEach((user) => {
//console.log("user.avatar_template: ", user.avatar_template);
let avatarTemplate = user.avatar_template.replace(/\{size\}/, "30");
avatarTemplate = avatarTemplate.startsWith("https://")
? avatarTemplate
: `${avatarUrl}${avatarTemplate}`;
img += `<img src="${avatarTemplate}" alt="${user.name}" />\n`;
});
return img;
};
const showLatestPosts = (obj) => {
//console.log("obj.users: ", obj.users);
//console.log("posters: ", obj.topic_list.topics[0].posters);
//console.log("obj.topic_list: ", obj.topic_list);
const postContainer = document.getElementById("posts-container");
postContainer.innerHTML = "";
obj.topic_list.topics.forEach((topic) => {
//console.log(topic.posters);
//console.log("#############################################");
//console.log(obj.users);
postContainer.innerHTML += `<tr>
<td>
<a class="post-title" href="${forumTopicUrl}${topic.slug}/${topic.id}">${topic.title}</a>
${forumCategory(topic.category_id)}
</td>
<td>
<div class="avatar-container">${avatars(topic.posters, obj.users)}</div>
</td>
<td>${topic.posts_count - 1}</td>
<td>${topic.views}</td>
<td>${timeAgo(topic.bumped_at)}</td>
</tr>`;
});
};
async function fetchData() {
try {
let response = await fetch(forumLatest);
let data = await response.json();
showLatestPosts(data);
} catch (error) {
console.log(error);
}
}
dhess
March 24, 2025, 4:12pm
3
What are the console errors?
I meant to say, there are no console errors. My bad, sorry.
dhess
March 24, 2025, 4:21pm
5
Would you post your HTML, please?
I did not make any change in the html but here you go:-
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>fCC Forum Leaderboard</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<header>
<nav>
<img
class="fcc-logo"
src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg"
alt="freeCodeCamp logo"
/>
</nav>
<h1 class="title">Latest Topics</h1>
</header>
<main>
<div class="table-wrapper">
<table>
<thead>
<tr>
<th id="topics">Topics</th>
<th id="avatars">Avatars</th>
<th id="replies">Replies</th>
<th id="views">Views</th>
<th id="activity">Activity</th>
</tr>
</thead>
<tbody id="posts-container"></tbody>
</table>
</div>
</main>
<script src="./script.js"></script>
</body>
</html>
and the css:-
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--main-bg-color: #2a2a40;
--black: #000;
--dark-navy: #0a0a23;
--dark-grey: #d0d0d5;
--medium-grey: #dfdfe2;
--light-grey: #f5f6f7;
--peach: #f28373;
--salmon-color: #f0aea9;
--light-blue: #8bd9f6;
--light-orange: #f8b172;
--light-green: #93cb5b;
--golden-yellow: #f1ba33;
--gold: #f9aa23;
--green: #6bca6b;
}
body {
background-color: var(--main-bg-color);
}
nav {
background-color: var(--dark-navy);
padding: 10px 0;
}
.fcc-logo {
width: 210px;
display: block;
margin: auto;
}
.title {
margin: 25px 0;
text-align: center;
color: var(--light-grey);
}
.table-wrapper {
padding: 0 25px;
overflow-x: auto;
}
table {
width: 100%;
color: var(--dark-grey);
margin: auto;
table-layout: fixed;
border-collapse: collapse;
overflow-x: scroll;
}
#topics {
text-align: start;
width: 60%;
}
th {
border-bottom: 2px solid var(--dark-grey);
padding-bottom: 10px;
font-size: 1.3rem;
}
td:not(:first-child) {
text-align: center;
}
td {
border-bottom: 1px solid var(--dark-grey);
padding: 20px 0;
}
.post-title {
font-size: 1.2rem;
color: var(--medium-grey);
text-decoration: none;
}
.category {
padding: 3px;
color: var(--black);
text-decoration: none;
display: block;
width: fit-content;
margin: 10px 0 10px;
}
.career {
background-color: var(--salmon-color);
}
.feedback,
.html-css {
background-color: var(--light-blue);
}
.support {
background-color: var(--light-orange);
}
.general {
background-color: var(--light-green);
}
.javascript {
background-color: var(--golden-yellow);
}
.backend {
background-color: var(--gold);
}
.python {
background-color: var(--green);
}
.motivation {
background-color: var(--peach);
}
.avatar-container {
display: flex;
justify-content: center;
gap: 10px;
flex-wrap: wrap;
}
.avatar-container img {
width: 30px;
height: 30px;
}
@media (max-width: 750px) {
.table-wrapper {
padding: 0 15px;
}
table {
width: 700px;
}
th {
font-size: 1.2rem;
}
.post-title {
font-size: 1.1rem;
}
}
dhess
March 24, 2025, 4:55pm
8
The first thing I notice is there is no data on your HTML page, meaning you’re not actually calling fetchData() in your JS code.
yes, you are right, fetchData() call was missing in my js code. Now I have added it but its still the same. also i believe that no change will be required in the provided html and css file, right?
const forumLatest =
"https://cdn.freecodecamp.org/curriculum/forum-latest/latest.json";
const forumTopicUrl = "https://forum.freecodecamp.org/t/";
const forumCategoryUrl = "https://forum.freecodecamp.org/c/";
const avatarUrl = "https://sea1.discourse-cdn.com/freecodecamp";
const allCategories = {
299: { category: "Career Advice", className: "career" },
409: { category: "Project Feedback", className: "feedback" },
417: { category: "freeCodeCamp Support", className: "support" },
421: { category: "JavaScript", className: "javascript" },
423: { category: "HTML - CSS", className: "html-css" },
424: { category: "Python", className: "python" },
432: { category: "You Can Do This!", className: "motivation" },
560: { category: "Backend Development", className: "backend" },
};
function timeAgo(isoTimestamp) {
const diffInMs = new Date() - new Date(isoTimestamp);
const diffInMins = Math.floor(diffInMs / (1000 * 60));
if (diffInMins < 60) {
return `${diffInMins}m ago`;
}
const diffInHours = Math.floor(diffInMins / 60);
if (diffInHours < 24) {
return `${diffInHours}h ago`;
}
const diffInDays = Math.floor(diffInHours / 24);
return `${diffInDays}d ago`;
}
//console.log(new Date().toISOString());
//console.log(timeAgo("2025-03-23T12:00:00Z")); // Output depends on current time
const viewCount = (numViews) => {
return numViews >= 1000 ? `${Math.floor(numViews / 1000)}k` : numViews;
};
const forumCategory = (id) => {
if (allCategories.hasOwnProperty(id)) {
return `<a class="category ${allCategories[id].className}" href="${forumCategoryUrl}${allCategories[id].className}/${id}">${allCategories[id].category}</a>`;
} else {
return `<a class="category general" href="${forumCategoryUrl}general/${id}">General</a>`;
}
};
//console.log(forumCategory("299"));
const avatars = (posters, users) => {
let img = "";
users
.filter((user) => posters.some((poster) => poster.user_id === user.id))
.forEach((user) => {
//console.log("user.avatar_template: ", user.avatar_template);
let avatarTemplate = user.avatar_template.replace(/\{size\}/, "30");
avatarTemplate = avatarTemplate.startsWith("https://")
? avatarTemplate
: `${avatarUrl}${avatarTemplate}`;
img += `<img src="${avatarTemplate}" alt="${user.name}" />\n`;
});
return img;
};
const showLatestPosts = (obj) => {
//console.log("obj.users: ", obj.users);
//console.log("posters: ", obj.topic_list.topics[0].posters);
//console.log("obj.topic_list: ", obj.topic_list);
const postContainer = document.getElementById("posts-container");
postContainer.innerHTML = "";
obj.topic_list.topics.forEach((topic) => {
//console.log(topic.posters);
//console.log("#############################################");
//console.log(obj.users);
postContainer.innerHTML += `<tr>
<td>
<a class="post-title" href="${forumTopicUrl}${topic.slug}/${topic.id}">${topic.title}</a>
${forumCategory(topic.category_id)}
</td>
<td>
<div class="avatar-container">${avatars(topic.posters, obj.users)}</div>
</td>
<td>${topic.posts_count - 1}</td>
<td>${topic.views}</td>
<td>${timeAgo(topic.bumped_at)}</td>
</tr>`;
});
};
async function fetchData() {
try {
let response = await fetch(forumLatest);
let data = await response.json();
showLatestPosts(data);
} catch (error) {
console.log(error);
}
}
fetchData();
dhess
March 24, 2025, 5:08pm
10
Yes. That’s right. All of the HTML data is being generated by your JS. Also, the tests probably are calling the fetchData() function for you, so I’ll keep looking.
UPDATE: The only thing I’m seeing is that avatars is sometimes not returning user images in same order as the users appear in the topic_list.topics.posters array.
you are right, i updated my avatars function to below and it worked, thanks!!
const avatars = (posters, users) => {
let img = "";
posters.forEach((poster) => {
const user = users.find((user) => user.id === poster.user_id);
if (user) {
let avatarTemplate = user.avatar_template.replace(/\{size\}/, "30");
avatarTemplate = avatarTemplate.startsWith("https://")
? avatarTemplate
: `${avatarUrl}${avatarTemplate}`;
img += `<img src="${avatarTemplate}" alt="${user.name}" />\n`;
}
});
return img;
};
system
Closed
September 23, 2025, 4:02pm
12
This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.