Flashcards project redux: Getting error when iterating through cards

Hello everyone,

I hope all is well. I am currently working on the Flashcards project in the redux section. Here is the link to the project: Flashcards project

I am currently on step 17 and I’m trying to iterate through the cards array. However I am encountering problems. Here is my newQuizForm.js file where I attempt to iterate through the card arrays:

import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import { v4 as uuidv4 } from "uuid";
import ROUTES from "../app/routes";
import{useSelector, useDispatch} from 'react-redux';
import {selectTopic} from '../features/topics/topicsSlice';
import { thunkActionCreator } from "../features/quizzes/quizSlice";
import { addCard } from "../features/cards/cardSlice";

export default function NewQuizForm() {
  const [name, setName] = useState("");
  const [cards, setCards] = useState([]);
  const [topicId, setTopicId] = useState("");
  const history = useHistory();
  const topics = useSelector(selectTopic);
  const dispatch = useDispatch();
  const id = uuidv4();

  const handleSubmit = (e) => {
    e.preventDefault();
    if (name.length === 0) {
      return;
    }

    const cardIds = [];
    const cardId= uuidv4();
    cardIds.push(cardId);
    

    console.log(cards);

    // create the new cards here and add each card's id to cardIds
    // create the new quiz here
    history.push(ROUTES.quizzesRoute());
    dispatch(thunkActionCreator({name,id,topicId,cardIds}));

    cards.forEach(i => {
      dispatch(addCard({id:cardId,front:cards[i].front,back:cards[i].back})
      )}
    );
    
  };

  const addCardInputs = (e) => {
    e.preventDefault();
    setCards(cards.concat({ front: "", back: "" }));
  };

  const removeCard = (e, index) => {
    e.preventDefault();
    setCards(cards.filter((card, i) => index !== i));
  };

  const updateCardState = (index, side, value) => {
    const newCards = cards.slice();
    newCards[index][side] = value;
    setCards(newCards);
  };

  return (
    <section>
      <h1>Create a new quiz</h1>
      <form onSubmit={handleSubmit}>
        <input
          id="quiz-name"
          value={name}
          onChange={(e) => setName(e.currentTarget.value)}
          placeholder="Quiz Title"
        />
        <select
          id="quiz-topic"
          onChange={(e) => setTopicId(e.currentTarget.value)}
          placeholder="Topic"
        >
          <option value="">Topic</option>
          {Object.values(topics).map((topic) => (
            <option key={topic.id} value={topic.id}>
              {topic.name}
            </option>
          ))}
        </select>
        {cards.map((card, index) => (
          <div key={index} className="card-front-back">
            <input
              id={`card-front-${index}`}
              value={cards[index].front}
              onChange={(e) =>
                updateCardState(index, "front", e.currentTarget.value)
              }
              placeholder="Front"
            />

            <input
              id={`card-back-${index}`}
              value={cards[index].back}
              onChange={(e) =>
                updateCardState(index, "back", e.currentTarget.value)
              }
              placeholder="Back"
            />

            <button
              onClick={(e) => removeCard(e, index)}
              className="remove-card-button"
            >
              Remove Card
            </button>
          </div>
        ))}
        <div className="actions-container">
          <button onClick={addCardInputs}>Add a Card</button>
          <button>Create Quiz</button>
        </div>
      </form>
    </section>
  );
}

However, I get this error when I add cards and submit the new quiz:

I’ve been quite confused as to why this is happening. I’ve been trying to figure this out for a while now and I am completely stumped. Any ideas as to why I am getting this error? Is there a better way to iterate through the cards array? Any help is appreciated. Thanks for your help everyone! Happy coding :slight_smile:

Hi,

I don’t know if this will solve your issue completely, but at least it might help a little.

I think on the foreach loop, the first param is the element being iterated itself (not the index), so I think card[i] will probably not be the value you’re expecting. (maybe calling i instead card would be clearer?) Again, just an idea.

2 Likes

Change:

From

cards.forEach(i => {
      dispatch(addCard({id:cardId,front:cards[i].front,back:cards[i].back})
   )}
);

To

cards.forEach((_, i) => {
      dispatch(addCard({id:cardId,front:cards[i].front,back:cards[i].back})
   )}
);

Or

cards.forEach(card) => {
      dispatch(addCard({id:cardId,front:card.front,back:card.back})
   )}
);
1 Like

Hi @elnicomapero82885037 ,

Thanks for pointing out that I am not passing the index, but the first parameter in the array. I will go ahead and try your recommendation! Thanks! Happy coding :slight_smile:

1 Like

Hi @4130994767

Thanks for your help! I was able to iterate through the card arrays. I have a question about one of the solutions you wrote. My question is about this solution:

cards.forEach((_, i) => {
      dispatch(addCard({id:cardId,front:cards[i].front,back:cards[i].back})
   )}
);

Why do we have to include a blank argument (_, i) so that we can pass through the index of the array?