Flashcards Challenge Project (Redux)

Hi everyone. This is my solution to the project.

Hi, this is my solution

Hello ladies and gents,

This is my solution for the flashcards project, Flashcards-starter and here is the link to the web page christsadi.github.io/flashcards-starter/

I just finished the flashcards project, and it was a large challenge! It took three days, and I also added extra features such as editing, deleting, and saving to local storage.

GitHub: GitHub - Blancher/quizstructor: An app made with React and Redux that allows users to create topics, make quizzes with flashcards pertaining to the topics, and use the created quizzes. In addition, you can also edit and delete topics and quizzes.

Deploy: https://quizstructor.web.app/

Hello,

Thanks for your solution!

for this project, in step 5, it mentioned the app state is :

{
topics: {
topics: {
‘123’: {
id: ‘123’,
name: ‘example topic’,
icon: ‘icon url’,
quizIds: [‘456’]
}
}
},
quizzes: {
quizzes: {
‘456’: {
id: ‘456’,
topicId: ‘123’,
name: ‘quiz for example topic’,
cardIds: [‘789’, ‘101’, ‘102’]
}
}
},
cards: {
cards: {
‘789’: {
id: ‘789’,
front: ‘front text’,
back: ‘back text’
},
‘101’: {
id: ‘101’,
front: ‘front text’,
back: ‘back text’
},
‘102’: {
id: ‘102’,
front: ‘front text’,
back: ‘back text’
},
}
}

why the suggested solution accessed state.topics[id] instead of state.topics.topics[id]?

i supposed state.topics is
{
topics: {
‘123’: {
id: ‘123’,
name: ‘example topic’,
icon: ‘icon url’,
quizIds: [‘456’]
}
}

Hello, this is Triston.

I am clueless as to how to fix my solution to this project. From Steps 10-14, it is instructed to create a quizzesSlice, add another action to topicsSlice, “write an action creator that returns a thunk that dispatches these two actions [creating a new quiz and associating it with the topic] one after the other,” and import and implement the necessary code into NewQuizForm.

However, when I go to create a new quiz in the final product, the list of topics I made previously does not appear in the drop-down menu. And I when I create the quiz, it does not appear in the Quizzes page.

Here are the relevant files.
quizzesSlice.js:

import { createSlice } from '@reduxjs/toolkit'; import { addQuizId } from '../topics/topicsSlice'; export const quizzesSlice = createSlice({ name: 'quizzes', initialState: { quizzes: {} }, reducers: { addQuiz: (state, action) => { const {quizId} = action.payload; state.quizzes[quizId] = action.payload; return state; } } }); export const addQuizPlusQuizId = (quiz) => { const { quizId, topicId } = quiz; return (dispatch) => { dispatch(quizzesSlice.actions.addQuiz(quiz)); dispatch(addQuizId({ quizId: quizId, topicId: topicId })); }; }; export const selectQuizzes = (state) => state.quizzes.quizzes; export const { addQuiz } = quizzesSlice.actions; export default quizzesSlice.reducer;

topicsSlice.js:

import { createSlice } from '@reduxjs/toolkit'; export const topicsSlice = createSlice({ name: 'topics', initialState: { topics: {} }, reducers: { addTopic: (state, action) => { state.topics[action.payload.topicId] = {...action.payload, quizId: []}; return state; } addQuizId: (state, action) => { const {topicId, quizId} = action.payload; state.topics[topicId].quizIds.push(quizId); } } }); export const selectTopics = (state) => state.topics.topics; export const { addTopic, addQuizId } = topicsSlice.actions; export default topicsSlice.reducer;

NewQuizForm.js:

import React, { useState } from "react"; import { useHistory } from "react-router-dom"; import { v4 as uuidv4 } from "uuid"; import ROUTES from "../app/routes"; import { addQuizPlusQuizId } from '../features/quizzes/quizzesSlice'; import { selectTopics } from '../features/topics/topicsSlice'; import { addCard } from '../features/cards/cardSlice'; import { useDispatch, useSelector } from "react-redux"; export default function NewQuizForm() { const [name, setName] = useState(""); const [cards, setCards] = useState([]); const [topicId, setTopicId] = useState(""); const history = useHistory(); const topics = useSelector(selectTopics); const dispatch = useDispatch(); const handleSubmit = (e) => { e.preventDefault(); if (name.length === 0) { return; } const cardIds = []; // create the new cards here and add each card's id to cardIds cards.forEach((card) => { let cardId = uuidv4(); cardIds.push(cardId); dispatch(addCard({ cardId: cardId, front: card.front, back: card.back })); }); // create the new quiz here dispatch(addQuizPlusQuizId({quizId: uuidv4(), name: name, topicId: topicId, cardIds: cardIds})); history.push(ROUTES.quizzesRoute()); }; 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> ); }

Is there anything I could be doing wrong? Feedback would be incredible.

Sincerely,

Triston

Done! GitHub - Cmastris/redux-flashcards: A Codecademy guided practice project using Redux (with React). Starter code (in the initial commit) was provided by Codecademy.

I’ve defiitely found the latest projects more challenging; there are a lot of new concepts and functions. For anyone who is struggling, I found that looking back on the previous completed project code (Redux News Reader) was very helpful when I was forgetting the concepts/patterns.

Hello Triston, I’ve gone through some of your code and one thing i can immediately see is, in your topicsSlice.js, you missed a comma between the two action creators. Also it would be helpful to see your store.js file as well.

I will also recommend that you do the project on VScode rather than codecademy platform, the use Devtools with your browser to debug the code. The reason for this is that, some errors thrown by your code don’t show up when on codecademy. Also, the errors you get when using vscode, browser and devTools are more informative and give you the line of error sometimes

Hi, you have to import 3 reducers for cards, quizzes and topics. Ensure you don’t use curly braces if you did export default on the slice page.

Installed locally. Haven’t even begun this yet but getting node errors when I try to get it running using npm start.

Here’s the error:

🚀 npm start

> [email protected] start
> react-scripts start

node:internal/modules/cjs/loader:553
      throw e;
      ^

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './lib/tokenize' is not defined by "exports" in /Users/figgefenk/Dev/Codecademy/flashcards-starter/node_modules/postcss-safe-parser/node_modules/postcss/package.json
    at new NodeError (node:internal/errors:405:5)
    at exportsNotFound (node:internal/modules/esm/resolve:260:10)
    at packageExportsResolve (node:internal/modules/esm/resolve:590:9)
    at resolveExports (node:internal/modules/cjs/loader:547:36)
    at Module._findPath (node:internal/modules/cjs/loader:621:31)
    at Module._resolveFilename (node:internal/modules/cjs/loader:1034:27)
    at Module._load (node:internal/modules/cjs/loader:901:27)
    at Module.require (node:internal/modules/cjs/loader:1115:19)
    at require (node:internal/modules/helpers:119:18)
    at Object.<anonymous> (/Users/figgefenk/Dev/Codecademy/flashcards-starter/node_modules/postcss-safe-parser/lib/safe-parser.js:1:17) {
  code: 'ERR_PACKAGE_PATH_NOT_EXPORTED'
}

Any ideas on how to get this working? I’d much prefer to do it locally with an associated github repo.

Ah simply running npm update seems to fix this but it causes another issue with dependencies. I suspect CC haven’t updated these projects for the latest versions. Node fixed a security hole but it broke some older changes.

I did some research and looks like running npm audit fix --force will fix it and allow the app to live update. Hope this helps others!

Hey, that Codevolution tutorial is helping me a lot to get my knowledge together so I can have a clear view of whats expected from us learners. Gracias!

1 Like

I’ve successfully completed the Flash Card project, and I’ve taken the liberty of adding some initial data to kickstart the experience with two quizzes ready to roll! :smile:

I’m eager to hear your thoughts and suggestions, so please feel free to review my code and provide any feedback you may have. Your insights are incredibly valuable! :rocket::speech_balloon:

Looking forward to the community’s feedback and sharing this learning journey together! :star2:

1 Like

I would like to make a point on these video tutos. They are really helpful to understand in a clear fashion Redux, Redux Toolkit, React - Redux. They are very well explained through a series of short videos, concise and to the point, paying emphasis on details that make the difference

1 Like

Here is my finished project. Was not very clear to me on how to associate quiz ids with the topic. So I changed it to where the quiz is associated by topic name.

1 Like

Hi!
in step 9, can anybody tell me where in the code does addQuiz action receives a payload of the form { id: '123', name: 'quiz name', topicId: '456', cardIds: ['1', '2', '3', ...]} ?

Here is my solution to the Flashcards project: Github
Curious as to why the solution codes topicsSlice exports an addQuizIdForTopic action. Was there a thunk requirement in previous iterations of this lesson?

Took advantage of the extraReducers property for updating the topicsSlice state using the addQuiz action from the quizzesSlice. Also, the Currying approach in the cardsSlice card selector.

2 Likes

addQuizIdForTopic do nothing. I think it’s typo from Codecademy. Because we have addQuiz action in quizzesSlice which make all job, and additionally pushing id to quizIds arr in topics state. Just made 2 things by one action type in different places.

2 Likes

Finally finished!
Here is my code:

Like some others said, I tried in the Codecademy environment first but then was getting an error, so I downloaded it and did it locally, which worked fine.
The instructions were a bit confusing at times, eg. in step 12 it says “you can test your code now and it should do XYZ”. It wasn’t working so I spent ages trying to work out why, but it turns out I had to complete step 13 before that would work. I think the same thing happened elsewhere, too.
Also it keeps using useSelector although that hasn’t been covered in the course, so it would have been great to get a lesson on that first.

Anyway I managed it in the end!

4 Likes

Hello! This project was finished from the Front-End Engineer Career Path.
This project can be quite a challenge as there are steps inside this project that you may not be quite familiar with at this point in the curriculum. (Some steps I really struggled with involve: correctly implementing the state for each slice, understanding [ useSelector ], step 13 needed to be complete to see any visual changes for step 12, (side note: there is an added “)” at the end of step 14’s hint, but it is a very minor typo)). Hopefully there will be some slight updates in the future to better address these parts of the project.
Flashcards

This project will be an excellent example to reference for future projects, any upcoming portfolio projects, and as a study guide to further practice your skills.

2 Likes