Build a Set of Football Team Cards - Build a Set of Football Team Cards

Tell us what’s happening:

In this Lab I am trying to filter some players based on their position, but I am having some trouble syntax wise with filtering their positioning.

Your code so far

<!-- file: index.html -->
<!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>
      Build a Set of Football Team Cards
    </title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <h1 class="title">Team stats</h1>
    <main>
      <div class="team-stats">
        <p>Team: <span id="team"></span></p>
        <p>Year: <span id="year"></span></p>
        <p>Head coach: <span id="head-coach"></span></p>
      </div>
      <label class="options-label" for="players">Filter Teammates:</label>
      <select name="players" id="players">
        <option value="all">All Players</option>
        <option value="forward">Position Forward</option>
        <option value="midfielder">Position Midfielder</option>
        <option value="defender">Position Defender</option>
        <option value="goalkeeper">Position Goalkeeper</option>
      </select>
      <div class="cards" id="player-cards"></div>
    </main>
    <footer>&copy; freeCodeCamp</footer>
    <script src="./script.js"></script>
  </body>
</html>

/* file: styles.css */

/* file: script.js */
const footballTeam = {
  team: "New England Patriots",
  year: 2026,
  headCoach: "Mike Vrabel",
  players: [
    {
      name: "Drake Maye",
      positon: "forward",
      isCaptain: true
    },
    {
      name: "Christian Gonzales",
      positon: "midfielder",
      isCaptain: false
    },
    {
      name: "Player Three",
      positon: "defender",
      isCaptain: false
    },
    {
      name: "Player Four",
      positon: "goalkeeper",
      isCaptain: false
    }
  ]
}

const teamEl = document.querySelector("#team");
const yearEl = document.querySelector("#year");
const headCoachEl = document.querySelector("#head-coach");

teamEl.textContent = footballTeam.team;
yearEl.textContent = footballTeam.year;
headCoachEl.textContent = footballTeam.headCoach;

const playerCardsEl = document.querySelector("#player-cards");
playerCardsEl.innerHTML = `<div class="player-card">
                              <h2>(Captain) Drake Maye</h2>
                              <p>Position: forward</p>
                          </div>
                          <div class="player-card">
                            <h2>Christian Gonzalez</h2>
                            <p>Position: midfielder</p>
                          </div>
                          <div class="player-card">
                            <h2>Player Three</h2>
                            <p>Position: defender</p>
                          </div>
                          <div class="player-card">
                            <h2>Player Four</h2>
                            <p>Position: goalkeeper</p>
                          </div>`;

function helperFunction(playerPosition) {
  const teammates = 
    playerPosition === "all"
    ? footballTeam.players
    // This ELSE condition for the ternary operator does NOT work
    : footballTeam.players.filter(({position}) => position ===     playerPosition);

    return teammates
      .map(({name, position}) => {
        return `<div class="player-card">
                  <h2>${name}</h2>
                  <p>Position: ${position}</p>
                </div>`;
      })
}

const playerListEl = document.querySelector("#players");

playerListEl.addEventListener("change", () => {
  playerCardsEl.innerHTML = helperFunction(players.value);
});

// Prints out entire array
// console.log(footballTeam.players);

// Unable to access property of object in subarray
console.log(footballTeam.players[0]);
console.log(footballTeam.players[0].position);

I added some comments in the script describing the issue I am having. I want to be able to access elements from the players property in the footballTeams array in a filtered manner. Meaning, I would like to only print out elements from the array that is the property’s value that correspond to a certain position. Like I would only like to display elements that contain the value “midfielder” or “forward”. I’m just confused syntax wise with the way this object is structured and I can’t chain things how I regularly would.

Also, I am aware that this is an american football team when it meant actual football in the instructions. I didn’t realize until later, but by then I already added in all the details.

Console Output:

{ name: 'Drake Maye', positon: 'forward', isCaptain: true }
undefined

Challenge Information:

Build a Set of Football Team Cards - Build a Set of Football Team Cards

Filter and ternary operator are both fine. However there’s a typo in the position attribute in the players list.

1 Like

Ah, that fixed it thank you!

However, I am still failing the following two test cases:

11. When the option All Players is selected, all players should be present within #player-cards.

12. When the option Position Forward is selected, only forward players should be present within #player-cards.

In the screenshots shown, the drop-down menu seems to work just fine visually. So, I am unsure as to why this is failing since the ternary operator is working as intended.

Script:

const footballTeam = {

  team: "New England Patriots",

  year: 2026,

  headCoach: "Mike Vrabel",

  players: [

    {

      name: "(Captain) Drake Maye",

      position: "forward",

      isCaptain: true

    },

    {

      name: "Christian Gonzales",

      position: "midfielder",

      isCaptain: false

    },

    {

      name: "Player Three",

      position: "defender",

      isCaptain: false

    },

    {

      name: "Player Four",

      position: "goalkeeper",

      isCaptain: false

    }

  ]

}




const teamEl = document.querySelector("#team");

const yearEl = document.querySelector("#year");

const headCoachEl = document.querySelector("#head-coach");




teamEl.textContent = footballTeam.team;

yearEl.textContent = footballTeam.year;

headCoachEl.textContent = footballTeam.headCoach;




const playerCardsEl = document.querySelector("#player-cards");

playerCardsEl.innerHTML = `<div class="player-card">

                              <h2>(Captain) Drake Maye</h2>

                              <p>Position: forward</p>

                          </div>

                          <div class="player-card">

                            <h2>Christian Gonzalez</h2>

                            <p>Position: midfielder</p>

                          </div>

                          <div class="player-card">

                            <h2>Player Three</h2>

                            <p>Position: defender</p>

                          </div>

                          <div class="player-card">

                            <h2>Player Four</h2>

                            <p>Position: goalkeeper</p>

                          </div>`;




function helperFunction(playerPosition) {

  const teammates = 

    playerPosition === "all"

    ? footballTeam.players

    : footballTeam.players.filter(({position}) => position ===     playerPosition);




    return teammates

      .map(({name, position}) => {

        return `<div class="player-card">

                  <h2>${name}</h2>

                  <p>Position: ${position}</p>

                </div>`;

      })

}




const playerListEl = document.querySelector("#players");




playerListEl.addEventListener("change", () => {

  playerCardsEl.innerHTML = helperFunction(players.value);

});

Hmm, there might be something fishy going on with the isCaptain attribute. If you open the browser’s console (not the console on page), there will be some details regarding failing tests.

1 Like

how are you identifying the captain here?

1 Like

playerCardsEl.innerHTML should not be hard coded.


It looks like you have hard-coded conditionals or variables that check for specific expected values. That is not solving this problem in the general case. Imagine if you were given different input values. Would your code be able to solve those problems?

To find out more about what hard-coding is or about why it is not suitable for solving coding questions, please read this post: Hard-coding For Beginners

Let us know if you have a question about how to make your code more flexible.

1 Like

For identifying whether a player is captain or not, I just included it in their name.

{

      name: "(Captain) Drake Maye",

      position: "forward",

      isCaptain: true

    }

that is not going to pass the tests, because then the tests expect (Captain) (Captain) Drake Maye

1 Like

you also need to fix the property name here

1 Like

Fair enough, I went ahead and removed the hard-coded approach. In it’s place I added a .forEach() callback function that references the array of objects.

const playerCardsEl = document.querySelector("#player-cards");

playerCardsEl.innerHTML = footballTeam.players.forEach(({name, position}) => {

  `<div class="player-card">

    <h2>${name}</h2>

    <p>Position: ${position}</p>

  </div>`;

});

Yes, of course. I noticed the spelling error which was brought up by someone else in the thread and fixed the mistakes.

const footballTeam = {

  team: "New England Patriots",

  year: 2026,

  headCoach: "Mike Vrabel",

  players: [

    {

      name: "Drake Maye",

      position: "forward",

      isCaptain: true

    },

    {

      name: "Christian Gonzales",

      position: "midfielder",

      isCaptain: false

    },

    {

      name: "Player Three",

      position: "defender",

      isCaptain: false

    },

    {

      name: "Player Four",

      position: "goalkeeper",

      isCaptain: false

    }

  ]

}

if you need more help please post all your code

1 Like

Yes, of course.

Here is my current up-to-date code:

const footballTeam = {

  team: "New England Patriots",

  year: 2026,

  headCoach: "Mike Vrabel",

  players: [

    {

      name: "Drake Maye",

      position: "forward",

      isCaptain: true

    },

    {

      name: "Christian Gonzales",

      position: "midfielder",

      isCaptain: false

    },

    {

      name: "Player Three",

      position: "defender",

      isCaptain: false

    },

    {

      name: "Player Four",

      position: "goalkeeper",

      isCaptain: false

    }

  ]

}




const teamEl = document.querySelector("#team");

const yearEl = document.querySelector("#year");

const headCoachEl = document.querySelector("#head-coach");




teamEl.textContent = footballTeam.team;

yearEl.textContent = footballTeam.year;

headCoachEl.textContent = footballTeam.headCoach;




const playerCardsEl = document.querySelector("#player-cards");

playerCardsEl.innerHTML = footballTeam.players.forEach(({name, position}) => {

  // Trying to account for if current player is captain or not

  if (footballTeam.players.isCaptain === true) {

    `<div class="player-card">

      <h2>Captain${name}</h2>

      <p>Position: ${position}</p>

    </div>`;

  } else {

    `<div class="player-card">

      <h2>${name}</h2>

      <p>Position: ${position}</p>

    </div>`;

  }

});




function helperFunction(playerPosition) {

  const teammates = 

    playerPosition === "all"

    ? footballTeam.players

    : footballTeam.players.filter(({position}) => position ===     playerPosition);




    return teammates

      .map(({name, position}) => {

        return `<div class="player-card">

                  <h2>${name}</h2>

                  <p>Position: ${position}</p>

                </div>`;

      })

}




const playerListEl = document.querySelector("#players");




playerListEl.addEventListener("change", () => {

  playerCardsEl.innerHTML = helperFunction(players.value);

});

Fixes made so far:

  • Removed the hard-coded approach for the innerHTML and instead used a .forEach() callback function.
  • Removed the spelling error for position”
  • I removed “(Captain)” from the name of the player whose isCaptain key is set equal to true. In its place, I tried to utilize an if-else block in the .forEach() callback function to assign HTML markup for the playerCardsEl element in the HTML document. So far this is where I am stuck, as it isn’t displaying the string “(Captain)” when the boolean value is true. Unless this approach is wrong.

index.html

<!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>

      Build a Set of Football Team Cards

    </title>

    <link rel="stylesheet" href="styles.css" />

  </head>

  <body>

    <h1 class="title">Team stats</h1>

    <main>

      <div class="team-stats">

        <p>Team: <span id="team"></span></p>

        <p>Year: <span id="year"></span></p>

        <p>Head coach: <span id="head-coach"></span></p>

      </div>

      <label class="options-label" for="players">Filter Teammates:</label>

      <select name="players" id="players">

        <option value="all">All Players</option>

        <option value="forward">Position Forward</option>

        <option value="midfielder">Position Midfielder</option>

        <option value="defender">Position Defender</option>

        <option value="goalkeeper">Position Goalkeeper</option>

      </select>

      <div class="cards" id="player-cards"></div>

    </main>

    <footer>&copy; freeCodeCamp</footer>

    <script src="./script.js"></script>

  </body>

</html>

styles.css

*,

*::before,

*::after {

  box-sizing: border-box;

  margin: 0;

  padding: 0;

}




:root {

  --dark-grey: #0a0a23;

  --light-grey: #f5f6f7;

  --white: #ffffff;

  --black: #000;

}




body {

  background-color: var(--dark-grey);

  text-align: center;

  padding: 10px;

}




.title,

.options-label,

.team-stats,

footer {

  color: var(--white);

}




.title {

  margin: 1.3rem 0;

}




.team-stats {

  display: flex;

  justify-content: space-around;

  flex-wrap: wrap;

  font-size: 1.3rem;

  margin: 1.2rem 0;

}




.options-label {

  font-size: 1.2rem;

}




.cards {

  display: flex;

  flex-wrap: wrap;

  justify-content: center;

  align-items: center;

}




.player-card {

  background-color: var(--light-grey);

  padding: 1.3rem;

  margin: 1.2rem;

  width: 300px;

  border-radius: 15px;

}




@media (max-width: 768px) {

  .team-stats {

    flex-direction: column;

  }

}

I do not see the brackets here tho

1 Like

I see, I just interpreted that it should be a string literal but I went ahead and replaced it using string interpolation.

const playerCardsEl = document.querySelector("#player-cards");

playerCardsEl.innerHTML = footballTeam.players.forEach(({name, position}) => {

  // Trying to account for if current player is captain or not

  if (footballTeam.players.isCaptain === true) {

    `<div class="player-card">

      <h2>${isCaptain}${name}</h2>

      <p>Position: ${position}</p>

    </div>`;

  } else {

    `<div class="player-card">

      <h2>${name}</h2>

      <p>Position: ${position}</p>

    </div>`;

  }

});

And what do you think this will display?

1 Like

Well, it will display trueDrake Maye given the variable contains a boolean value and not a string. I assumed the test case would pass it given that’s how it expects the format to be. I guess I am confused on how the captain should be properly formatted as a string without hard-coding it.

Edit:
Sorry, I may have gotten confused with what the other person had said. They asked where the brackets were and I had assumed it should’ve been some form of variable. I currently reverted it back to the following:

if (footballTeam.players.isCaptain === true) {

    `<div class="player-card">

      <h2>(Captain)${name}</h2>

      <p>Position: ${position}</p>

    </div>`;

  } else {

    `<div class="player-card">

      <h2>${name}</h2>

      <p>Position: ${position}</p>

    </div>`;

  }


However, albeit this approach may be invalid…the HTML markup doesn’t seem to be displayed for the if block. Only the HTML markup in the else blocks are displayed for some reason.

I also added this approach to the second callback function .map() in the helperFunction() to deal with when the user clicks on different menu options and back on the all option in the dropdown menu.

function helperFunction(playerPosition) {

  const teammates = 

    playerPosition === "all"

    ? footballTeam.players

    : footballTeam.players.filter(({position}) => position ===     playerPosition);




    return teammates

      .map(({name, position}) => {

        if (footballTeam.players.isCaptain === true) {

          return `<div class="player-card">

                    <h2>(Captain)${name}</h2>

                    <p>Position: ${position}</p>

                  </div>`;

        } else {

          return `<div class="player-card">

                    <h2>${name}</h2>

                    <p>Position: ${position}</p>

                  </div>`;

        }

      })

}

Okay, I finally solved the Lab and realized a mistake I was making. One step I was making extra complicated for myself and made the following change:

.map(({name, position, isCaptain})

I am unable to post the full code or larger piece of code since my work now has the solution. Thank you to everyone that helped me!