I am having issues using a handleDelete function that is passed down to a grandchild with all the necessary props.
The structure of my components can go either: Deck > CardSlider > Card or Deck > Card, depending on if the user is in grid or carousel view. When I call the handleDelete function from Deck -> Card component (grid view), I am able to successfully delete the card, however I can't delete when I go from Deck -> CardSlider -> Card in carousel view.
When I check the network in chrome devtools, it shows a 200 status code for DELETE, however it doesn't actually delete!
I'm completely stumped. Any ideas?
async function handleDeleteCard(cardId: number) {
const newDeck = await deleteCard(deckId, cardId)
setCards(newDeck.cards);
}
return (
<div className="deck">
{view == 'grid' ?
<ul className="cards">
{cards.map((card, cardId) =>
<li key={cardId}>
<Card
card={card}
cardBack={cardBack}
cardFront={cardFront}
cardId={cardId}
flippedCard={flippedCard}
handleDeleteCard={handleDeleteCard}
handleFlip={handleFlip}
mode={mode}
view={view}
/>
</li>)}
</ul>
:
<CardSlider
cards={cards}
cardBack={cardBack}
cardFront={cardFront}
flippedCard={flippedCard}
handleFlip={handleFlip}
handleDeleteCard={handleDeleteCard}
mode={mode}
view={view}
/>
}
)
I tried passing the Card component all the necessary props from the CardSlider component in order to delete the card in caroussel view. I get the proper card ID and deck ID when I log the card details to be deleted in the handleDelete function, however it doesn't actually get deleted
The issue is that you give cardId
2 different meanings:
Deck
> Card
, cardId
is the index of the card within the cards
array:// cardId is the 2nd parameter of map callback,
// i.e. the index in the array being mapped
cards.map((card, cardId) =>
<li key={cardId}>
<Card
card={card}
cardId={cardId} // Index
handleDeleteCard={handleDeleteCard}
/>
</li>)
Deck
> CardSlider
> Card
, it is now the card._id
property (ObjectId
or string
from MongoDB document?)<Card
card={cards[currentIndex]}
cardId={cards[currentIndex]._id} // Document identifier, instead of index
// handleDeleteCard={() => handleDeleteCard(cards[currentIndex]._id)}
/>
When you monitor the DELETE
request, you should see the difference in cardId
argument.
When I call the handleDelete function from Deck -> Card component (grid view), I am able to successfully delete the card, however I can't delete when I go from Deck -> CardSlider -> Card in carousel view.
This means that your Backend knows only how to handle cardId
as the card index within an array of cards, but not as the card._id
field.
While an immediate solution could be to bring consistency in cardId
meaning by changing what CardSlider
uses (I suspect that it loops in the same order over the cards
array, so it should be able to generate the same index, very probably already as currentIndex
):
<Card
card={cards[currentIndex]}
cardId={currentIndex} // Index, assuming it is in the same order as in cards array?
handleDeleteCard={() => handleDeleteCard(currentIndex)}
/>
...a more robust solution would on the contrary change Deck
and your Backend, so that they handle the actual card._id
value (which is really a "cardId" and not just an "index").
That way, you would be able to delete any arbitrary card in a deck, even if the cards
array is shuffled for example.