Build an fCC Forum Leaderboard - Build an fCC Forum Leaderboard

Tell us what’s happening:

Hi, cannot pass 22 and 24, everything seems fine though. It’s the avatars function.
22. Each img element in the string returned by the avatars function should have an alt text with the value of the name property of the poster.
24. 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 /<avatar_template>.

Your code so far

<!-- file: index.html -->

/* file: styles.css */

/* file: script.js */

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' }
};

const postsContainer = document.getElementById('posts-container');

const timeAgo = (isoTimestamp) => {
  const isoToReadable = new Date(isoTimestamp);
  const now = new Date();

  if (now - isoToReadable < 60 * 60 * 1000) {
    return `${parseInt((now - isoToReadable) / 1000 / 60)}m ago`;
  } else if (now - isoToReadable < 24 * 60 * 60 * 1000) {
    return `${parseInt((now - isoToReadable) / 1000 / 60 / 60)}h ago`;
  } else {
    return `${parseInt((now - isoToReadable) / 1000 / 60 / 60 / 24)}d ago`;
  }
}

const viewCount = (views) =>
  views >= 1000 ? `${Math.floor(views / 1000)}k` : views;

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>`
  }
}

const avatars = (posters, users) => {
  return posters.map(poster => {
    const user = users.find(user => user.id === poster.user_id);

    if (!user) return '';
    const avatarPath = user.avatar_template.replace('{size}', 30);
    const userAvatarUrl = avatarPath.startsWith('/')
      ? `${avatarUrl}${avatarPath}`
      : avatarPath; 
    return `<img src='${userAvatarUrl}' alt='${user.name}'>`;
  }).join('');
};

const showLatestPosts = data => {
  const { users, topic_list } = data;
  const { topics } = topic_list;

  postsContainer.innerHTML =
    topics.map(item => {
      const { id, title, views, posts_count, slug, posters, category_id, bumped_at } = item;
      return `<tr>
            <td>
              <a class='post-title' href='${forumTopicUrl}${slug}/${id}'>${title}</a>
              ${forumCategory(category_id)}
            </td>
            <td>
              <div class='avatar-container'>
                ${avatars(posters, users)}
              </div>
            </td>
            <td>
              ${posts_count - 1}
            </td>
            <td>
              ${viewCount(views)}
            </td>
            <td>
              ${timeAgo(bumped_at)}
            </td>
          </tr>`
    }).join('');
}

const fetchData = async () => {
  try {
    const res = await fetch(forumLatest);
    const data = await res.json();
    showLatestPosts(data);
  } catch (err) {
    console.log(err)
  }
}

fetchData();

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36

Challenge Information:

Build an fCC Forum Leaderboard - Build an fCC Forum Leaderboard

1 Like

@rosabells
This is not the way. Please open your own threads in the future, this is just ridiculous

Any help would be much appreciated.

Please send a link to this and we will look at it.

I have edited your post so now the infos at the bottom of the post are not in the code block

1 Like

Shouldn’t map return a string only if a user is found?

I changed that with

const avatars = (posters, users) => {
  return posters.map(poster => {
    const user = users.find(user => user.id === poster.user_id);

    if (user) {

    const avatarPath = user.avatar_template.replace('{size}', 30);
    const userAvatarUrl = avatarPath.startsWith('/')
      ? `${avatarUrl}${avatarPath}`
      : avatarPath; 
    return `<img src='${userAvatarUrl}' alt='${user.name}'>\n`;
  }
  }).join('');
};

but nothing changed, same errors as before…

I’ve edited your post to improve the readability of the code. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (').

Thank, I will from now on.

What have you already done to troubleshoot here?

Try adding some console.log messages to confirm that your variables are returning what they should. Need to gather some debugging information.

Yeah. I think there’s an issue with the tests being a bit too restrictive. I absolutely could not find anything wrong with your code, so I’ve been playing with it, and when I changed the single quotes around your img attributes to double quotes, the tests passed. I’ll create an issue for this.

1 Like

Yes, it was the single quotes …!!
Thanks mate.

Everything was fine, the logs were fine, the page was showing correctly. It was just the single quotes on that single part of the avatars function. Btw I used single quotes throughout the the whole challenge…

1 Like

Not sure if this is related but:

I do try to use double quotes around HTML attributes as a standard just in case it ends up in a single quotes JS string, it does not get broken, which is a problem I’ve had before.

So double quotes always makes me think of HTML attribute and single quotes I associate with JS string. When they get mixed it’s always string = '<img src="URL" alt="value">'.

1 Like

That makes perfect sense. Thanks for sharing your thoughts.

1 Like