Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript Building Applications with React and Redux Putting it all Together Solution: The Player Detail Component

Matt Rabe
Matt Rabe
2,950 Points

REMOVE_PLAYER and selectedPlayerIndex bug, with solution

Because this project uses index to track players instead of some uid, a bug occurs when the user removes a player whose index is <= the current selectedPlayerIndex. Reproduce it:

  1. Open the app
  2. Click on the last player
  3. Observe the player's details correctly displayed in the PlayerDetail component at bottom
  4. Click the "X" next to the last player to remove that player.
  5. Observe error in console: Uncaught TypeError: Cannot read property 'name' of undefined

Also:

  1. Open the app
  2. Click on the first player
  3. Observe the player's details correctly displayed in the PlayerDetail component at bottom
  4. Click the "X" next to the first player to remove that player.
  5. Observe that the PlayerDetail component now unexpectedly shows the details for the second player, even though we never clicked on that player.

This is because the REMOVE_PLAYER reducer does not return an updated selectedPlayerIndex, even though the landscape of the indexes has been changed by removing a player.

In a more robust app the appropriate way to handle this would be to use some UID instead of indexes, but for the purposes of this project, a simple bugfix would be to use a bit of logic to return an updated selectedPlayerIndex in the REMOVE_PLAYER reducer like so:

case PlayerActionTypes.REMOVE_PLAYER:
  return {
    ...state,
    players: [
      ...state.players.slice(0, action.index),
      ...state.players.slice(action.index + 1)
    ],
    selectedPlayerIndex: (state.selectedPlayerIndex === action.index ? -1 : (state.selectedPlayerIndex > action.index ? state.selectedPlayerIndex - 1 : state.selectedPlayerIndex)),
  };

This snippet ensures that if the user removes the currently selected player selectedPlayerIndex will become -1 (thereby hiding the PlayerDetail component), and if the user removes a player with an index that is less than the index of the currently selected player selectedPlayerIndex will be adjusted down by one to accommodate for the shift in indexes.

Steven Parker
Steven Parker
217,602 Points

There ya go, now it's fully linked in. Don't forget to also notify the staff.

Matt Rabe
Matt Rabe
2,950 Points

Thanks for the help getting this thread correctly attached, Steven. The other thread is now deleted :)

3 Answers

Adam Beer
Adam Beer
11,313 Points

Thanks your solution! It's great, now working fine!

Cristina Rosales
Cristina Rosales
10,929 Points

My fix was way simpler. I just put a span tag around the {name} in Player and had the onClick event on the new span element.

like so:

      <span onClick={()=>props.selectPlayer(props.index)}>{props.name}</span>
Birthe Vandermeeren
Birthe Vandermeeren
17,146 Points

That's what I thought first too, but this doesn't always display the details you'd expect either. Take for example: You select the first player, then remove it, then it displays the details of the new first player, while you expect it to show the "Click ..." text again.

Birthe Vandermeeren
Birthe Vandermeeren
17,146 Points

I agree that in a more robust app the appropriate way to handle this would be to use some UID instead of indexes. While I understand your solution, I went with a simpeler one: setting the selectedPlayerIndex back to -1 when a player gets removed. Now the "Click ..." text always appears when you remove one of the players.