Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

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
231,269 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,314 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.