React problem Cannot read properties of undefined (reading 'map') in a quiz app? - javascript

I am working on a quiz project. Particularly I am working on selecting an answer out of 4 options. Whenever I click on an option I am encountering an error which is given below
This is my App.js file
import { useEffect, useState } from "react";
import Quiz from "./components/Quiz";
import { nanoid } from "nanoid";
function App() {
const [showScreen, setShowScreen] = useState(false);
const [quizData, setQuizData] = useState([]);
useEffect(() => {
fetch("https://opentdb.com/api.php?amount=5&category=21&type=multiple")
.then((res) => res.json())
.then((data) =>
setQuizData(
data.results.map((question) => {
return {
...question,
id: nanoid(),
answers: shuffle([
...question.incorrect_answers,
question.correct_answer,
]),
correct_answer: question.correct_answer,
};
})
)
);
}, []);
function shuffle(arr) {
let array = arr.map((ans) => {
return {
id: nanoid(),
answer: ans,
isSelected: false,
};
});
for (let i = array.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
let temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
function handleSelect(id, selectedAnsId) {
console.log(id, selectedAnsId);
setQuizData((prevQuizData) => {
console.log(quizData);
prevQuizData.map((question) => {
return question.id === id
? {
...question,
answers: question.answers.map((answer) => {
return answer.id === selectedAnsId
? {
...answer,
isSelected: !answer.isSelected,
}
: { ...answer, isSelected: false };
}),
}
: question;
});
});
}
const newQuizData = quizData.map((question) => {
return (
<Quiz
key={question.id}
id={question.id}
question={question.question}
answers={question.answers}
handleSelect={handleSelect}
/>
);
});
function openSeparateScreen() {
setShowScreen((prevShowScreen) => !prevShowScreen);
}
return (
<div className="App">
{showScreen ? (
<div className="quiz-container">
{newQuizData}
<button
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
margin: "auto",
}}
className="btn"
>
Check answers
</button>
</div>
) : (
<div className="container">
<h1 className="heading">Quizzical</h1>
<p className="text">To start a quiz please click on the button</p>
<button className="btn" onClick={openSeparateScreen}>
Start Quiz
</button>
</div>
)}
</div>
);
}
export default App;
This is my Quiz.js file
import React from "react";
const Quiz = (props) => {
return (
<>
<div className="questions">
<h3>{props.question}</h3>
<div className="options">
{props.answers.map((answer) => {
return (
<h6
key={answer.id}
className={`${
answer.isSelected ? "isSelected" : "transparent"
}`}
onClick={() => props.handleSelect(props.id, answer.id)}
>
{answer.answer}{" "}
</h6>
);
})}
</div>
</div>
<hr />
</>
);
};
export default Quiz;
The error message shows I am getting the error at line 66 which starts from
const newQuizData = quizData.map((question) => {
return (
<Quiz
key={question.id}
id={question.id}
question={question.question}
answers={question.answers}
handleSelect={handleSelect}
/>
);
});
any kind of help would be much appreciated.

Your quizData is undefined at some point.
The most likely culprit is
setQuizData((prevQuizData) => {
console.log(quizData);
prevQuizData.map((question) => {
you don't return the value there; try to change it to return prevQuizData.map((question) => {

Related

Getting first values from objects instead of getting that was chosen by user

Function holdAnswer has to change the property isChosen from false to true and mutate state, adding new value to the questions. Then function checkAnswers has to find answers that user has chosen and compare if the selected answers have property isCorrect, which has to be true. And if isCorrect is true and isChosen is true, function checkAnswers has to change the score count. It keeps showing me only the first answers, no matter what the user chose. Why it doesn't show me the answers which user chose?
Please take a look at Codesandbox
App.js
import { useState } from "react";
import QuestionSet from "./components/QuestionSet";
import Answers from "./components/Answers";
import { nanoid } from "nanoid";
function App() {
const [isQuesLoaded, setIsQuesLoaded] = useState(false);
const [questions, setQuestions] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [score, setScore] = useState(0);
async function startQuiz() {
try {
setIsQuesLoaded(!isQuesLoaded);
const response = await fetch(
"https://opentdb.com/api.php?amount=5&category=12&difficulty=easy&type=multiple"
);
const data = await response.json();
const allQuestions = data.results;
const listOfQuestions = allQuestions.map((item) => {
const allAnswers = [
{
id: nanoid(),
isCorrect: false,
isChosen: false,
answer: item.incorrect_answers[0]
},
{
id: nanoid(),
isCorrect: false,
isChosen: false,
answer: item.incorrect_answers[1]
},
{
id: nanoid(),
isCorrect: false,
isChosen: false,
answer: item.incorrect_answers[2]
},
{
id: nanoid(),
isCorrect: true,
isChosen: false,
answer: item.correct_answer
}
];
return {
id: nanoid(),
question: item.question,
answers: allAnswers
};
});
setQuestions(listOfQuestions);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}
function holdAnswer(questionId, answerId) {
console.log({ questionId, answerId });
setQuestions((prevQuestion) =>
prevQuestion.map((question) =>
question.id === questionId
? {
...question,
answers: question.answers.map((answer) =>
answer.id === answerId
? { ...answer, isChosen: !answer.isChosen }
: answer
)
}
: question
)
);
}
function checkAnswers() {
let correctCount = 0;
questions.forEach(question => {
const selectedAnswer = question.answers.find(answer => answer.answer.id === answer.answer.isChosen);
if (selectedAnswer.isCorrect) correctCount += 1;
setScore(correctCount);
console.log(correctCount);
console.log(selectedAnswer);
})
}
const questionElm = questions.map((question, index) => {
return (
<section key={index}>
<QuestionSet question={question.question} key={question.id} />
<Answers
answers={question.answers}
isChosen={question.answers.isChosen}
holdAnswer={(answerId) => holdAnswer(question.id, answerId)}
/>
</section>
);
});
return (
<div className="App">
{!isQuesLoaded ? (
<main>
<h1 className="title-app">Quizzical</h1>
<p className="desc-app">Some description if needed</p>
<button className="btn" onClick={startQuiz}>
Start Quiz
</button>
</main>
) : (
<main className="quest-box">
{loading && <div>Loading data...</div>}
{error && <div>{`There is a problem fetchning data = ${error}`}</div>}
<section className="quest-content">{questionElm}</section>
<button className="answer-btn" onClick={checkAnswers}>Check Answers</button>
</main>
)}
</div>
);
}
export default App;
Answers.js
function Answer(props) {
const styles = {
backgroundColor: props.answer.isChosen ? "#D6DBF5" : "transparent"
};
return (
<div
className="answer-div"
style={styles}
id={props.answer.id}
onClick={() => props.holdAnswer(props.answer.id)}
>
<p>{props.answer.answer}</p>
</div>
);
}
export default function Answers(props) {
return (
<section className="answer-container">
{props.answers.map((answer) => (
<Answer holdAnswer={props.holdAnswer} answer={answer} key={answer.id} />
))}
</section>
);
}
QuestionSet.js
export default function QuestionSet(props) {
return (
<section className="quest" key={props.id}>
<p>{props.question}</p>
</section>
);
}
First thing that I'm seeing is that you are passing holdAnswer function down via props on a wrong way
You need to change to something this (Simplified for convenience):
App.js
<Answers
answers={question.answers}
isChosen={question.answers.isChosen}
holdAnswer={
holdAnswer(question.id, answerId) // Telling what to execute from here (Without the param on the arrow function)
}
/>
Answers.js
<Answer holdAnswer={
props.holdAnswer // passing the whole function knowing what to execute
}
/>
Answer
<button onClick={() =>
props.holdAnswer // knowing what to do from App.js
}
/>
Or you can do it like this:
App.js
<Answers
answers={question.answers}
isChosen={question.answers.isChosen}
holdAnswer={
holdAnswer // passing the whole function to execute it in another component
}
/>
Answers.js
<Answer holdAnswer={
props.holdAnswer // passing the whole function to execute it in another
}
/>
Answer
<button onClick={() =>
props.holdAnswer(props.param1, props.param2) // executing the function here passing the parameters
}
/>
Not sure if this is going to fix your problem but at least it can simplify it.

Get undefined value from props on onClick event meanwhile the whole props are displaying well

I'm stuck getting undefined value when clicking on Answers "buttons". It has to console.log the id of this button which was generated by nanoid().
Questions.js
import { useState, useEffect } from "react";
import { nanoid } from "nanoid";
import QuestionSet from "./QuestionSet";
import Answers from "./Answers";
export default function Questions() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch(
"https://opentdb.com/api.php?amount=5&category=12&difficulty=easy&type=multiple"
)
.then((response) => {
if (!response.ok) {
throw new Error(
`This is an HTTP error: The status is ${response.status}`
);
}
return response.json();
})
.then((actualData) => {
setData(actualData.results);
setError(null);
})
.catch((err) => {
setError(err.message);
setData(null);
})
.finally(() => {
setLoading(false);
});
}, []);
const listOfQuestions = data.map((item) => {
const allAnswers = [
{ id: nanoid(), isCorrect: false, answer: item.incorrect_answers[0] },
{ id: nanoid(), isCorrect: false, answer: item.incorrect_answers[1] },
{ id: nanoid(), isCorrect: false, answer: item.incorrect_answers[2] },
{ id: nanoid(), isCorrect: true, answer: item.correct_answer },
];
return {
id: nanoid(),
question: item.question,
answers: allAnswers,
};
});
function holdAnswer(id) {
console.log(id);
}
const questionElm = listOfQuestions.map((question, index, i) => {
return (
<section key={index}>
<QuestionSet question={question.question} key={question.id} />
<Answers
answers={question.answers}
isChosen={question.isChosen}
id={question.answers.id}
holdAnswer={() => holdAnswer(question.answers.id)}
/>
</section>
);
});
return (
<main className="quest-box">
<section className="quest-content">{questionElm}</section>
<button className="answer-btn">Check Answers</button>
{loading && <div>Loading data...</div>}
{error && <div>{`There is a problem fetchning data = ${error}`}</div>}
</main>
);
}
QuestionSet.js (component)
export default function QuestionSet(props) {
return (
<section className="quest" key={props.id}>
<p>{props.question}</p>
</section>
);
}
Answers.js (component)
export default function Answers(props) {
const styles = {
backgroundColor: props.isChosen ? "#D6DBF5" : "transparent",
};
return (
<section className="answer-container">
<div
className="answer-div"
style={styles}
id={props.answers[3].id}
onClick={props.holdAnswer}
>
<p>{props.answers[3].answer}</p>
</div>
<div
className="answer-div"
style={styles}
id={props.answers[1].id}
onClick={props.holdAnswer}
>
<p>{props.answers[1].answer}</p>
</div>
<div
className="answer-div"
style={styles}
id={props.answers[2].id}
onClick={props.holdAnswer}
>
<p>{props.answers[2].answer}</p>
</div>
<div
className="answer-div"
style={styles}
id={props.answers[0].id}
onClick={props.holdAnswer}
>
<p>{props.answers[0].answer}</p>
</div>
</section>
);
}
Other props are displayed well such as questions and answer text. Also, I tested if the id of questions will be displaying and it works, but not the ids of the answers.
Why does it happen? Why does the part of allAnswers array are showing but the part with ids doesn't? :(
You are doing a few things wrong.
There is no question.answers.id it is an array, what you want is question.answers[0].id
Even with 1 sorted out, the way you handle the click is wrong, you need to just pass the function down to the child component, and let the child component handle it by itself
This is how your code will look like
Questions.js
import { useState, useEffect } from "react";
import { nanoid } from "nanoid";
import QuestionSet from "./QuestionSet";
import Answers from "./Answers";
export default function Questions() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch(
"https://opentdb.com/api.php?amount=5&category=12&difficulty=easy&type=multiple"
)
.then((response) => {
if (!response.ok) {
throw new Error(
`This is an HTTP error: The status is ${response.status}`
);
}
return response.json();
})
.then((actualData) => {
setData(actualData.results);
setError(null);
})
.catch((err) => {
setError(err.message);
setData(null);
})
.finally(() => {
setLoading(false);
});
}, []);
const listOfQuestions = data.map((item) => {
const allAnswers = [
{ id: nanoid(), isCorrect: false, answer: item.incorrect_answers[0] },
{ id: nanoid(), isCorrect: false, answer: item.incorrect_answers[1] },
{ id: nanoid(), isCorrect: false, answer: item.incorrect_answers[2] },
{ id: nanoid(), isCorrect: true, answer: item.correct_answer }
];
return {
id: nanoid(),
question: item.question,
answers: allAnswers
};
});
function holdAnswer(id) {
console.log(id);
}
const questionElm = listOfQuestions.map((question, index, i) => {
return (
<section key={index}>
<QuestionSet question={question.question} key={question.id} />
<Answers
answers={question.answers}
isChosen={question.isChosen}
holdAnswer={holdAnswer}
/>
</section>
);
});
return (
<main className="quest-box">
<section className="quest-content">{questionElm}</section>
<button className="answer-btn">Check Answers</button>
{loading && <div>Loading data...</div>}
{error && <div>{`There is a problem fetchning data = ${error}`}</div>}
</main>
);
}
Answers.js
export default function Answers(props) {
console.log(props);
const styles = {
backgroundColor: props.isChosen ? "#D6DBF5" : "transparent"
};
return (
<section className="answer-container">
<div
className="answer-div"
style={styles}
id={props.answers[3].id}
onClick={() => props.holdAnswer(props.answers[3].id)}
>
<p>{props.answers[3].answer}</p>
</div>
<div
className="answer-div"
style={styles}
id={props.answers[1].id}
onClick={() => props.holdAnswer(props.answers[3].id)}
>
<p>{props.answers[1].answer}</p>
</div>
<div
className="answer-div"
style={styles}
id={props.answers[2].id}
onClick={() => props.holdAnswer(props.answers[3].id)}
>
<p>{props.answers[2].answer}</p>
</div>
<div
className="answer-div"
style={styles}
id={props.answers[0].id}
onClick={() => props.holdAnswer(props.answers[3].id)}
>
<p>{props.answers[0].answer}</p>
</div>
</section>
);
}
Here is a working solution
https://codesandbox.io/s/vigilant-silence-tg43w0?file=/src/Answers.js:0-1116
Just to mention, there are a few optimization to be done for the code, but since it doesn't affect the question, I left it out, we can pick that off in the comment section

Ionic Capacitor App eventlistner plugin called multiple times in a single click

I am using Ionic capacitor to build my reactjs Web application. I have added a Capacitor App Apis to get the back event capture in my App.js file like this,
APPS.addListener("backButton", () => {
if (renderedScreenUIList.length === 0) {
// APPS.exitApp();
alert("exit app");
} else {
alert("previous screen");
}
});
But when i press back button this back event is called 3 times instead of one. my App.js file is.
// import "./StyleSeets/LightTheme.css";
import "./StyleSeets/theme.css";
import "./App.css";
import React, { useEffect, useState } from "react";
import Drawer from "#mui/material/Drawer";
import { App as APPS } from "#capacitor/app";
import Login from "./Components/Login";
import ERPUtils from "./Components/ERPUtils";
import Main from "./Components/Main";
// ************************** back fire event handling ****************
const renderedScreenUIList = [];
function App() {
// const [ stylePath, setStylePath ] = useState("./StyleSeets/LightTheme.css");
const [renderPageType, setRenderPageType] = useState("login");
const [isMobileView, setIMobileView] = useState(window.innerWidth < 920);
const isConsoleOpen = false;
window.onresize = function () {
console.log(window.outerHeight - window.innerHeight);
if ((window.outerHeight - window.innerHeight) > 100) { console.log("open"); } else console.log("close");
};
const themeList = [
{ value: "#2776ed", label: "light" },
{ value: "#45b11c", label: "nature" },
{ value: "#2AB67B", label: "evening" },
{ value: "#add8e6", label: "sky" },
{ value: "#2b035b", label: "dark" }];
const languageList = [
{ value: "ENG", label: "English" },
{ value: "MAL", label: "മലയാളം" },
{ value: "HIND", label: "हिन्दी" }];
const [language, setLanguage] = useState("ENG");
const onThemeChangeCall = () => {
const themeName = sessionStorage.getItem("theme-name");
const themeElement = document.getElementById("app-theme");
themeElement.className = "App";
document.documentElement.setAttribute("data-theme", themeName);
};
APPS.addListener("backButton", () => {
if (renderedScreenUIList.length === 0) {
// APPS.exitApp();
alert("exit app");
} else {
alert("previous screen");
}
});
const languageChanged = (type) => {
setLanguage(type);
};
useEffect(() => {
onThemeChangeCall();
}, []);
const changePage = (page) => {
setRenderPageType(page);
};
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
const changeTheme = (type) => {
sessionStorage.setItem("theme-name", type);
document.documentElement.classList.add("color-theme-in-transition");
window.setTimeout(() => {
document.documentElement.classList.remove("color-theme-in-transition");
}, 1000);
onThemeChangeCall();
};
const toggleDrawer = (value) => {
setIsSettingsOpen(value);
};
const changeLanguage = (type) => {
sessionStorage.setItem("language-theme", type);
languageChanged(type);
};
useEffect(() => {
setIMobileView(window.innerWidth < 920);
}, [window.innerWidth]);
return (
<div className="App" id="app-theme">
{renderPageType === "login"
? (
<Login
onThemeChangeCall={onThemeChangeCall}
changePage={changePage}
languageChanged={languageChanged}
toggleDrawer={toggleDrawer}
/>
)
: null}
{renderPageType === "home"
? (
<Main
onThemeChangeCall={onThemeChangeCall}
changePage={changePage}
languageChanged={languageChanged}
toggleDrawer={toggleDrawer}
isMobileView={isMobileView}
/>
)
: null}
<Drawer
anchor="right"
open={isSettingsOpen}
onClose={() => toggleDrawer(false)}
>
<div className="p-2 " style={{ width: "250px", backgroundColor: "var(--primaryBackground)" }}>
<h6 className="border-bottom p-2">Themes</h6>
<div className="">
{!ERPUtils.isNullorWhiteSpace(themeList) ? themeList.map((el, index) => (
<div
key={index}
onKeyDown={(e) => {
if (ERPUtils.isKeyBoardEnterPressed(e)) {
changeTheme(el.label);
}
}}
role="button"
tabIndex={0}
className="p-2 d-flex align-items-center font-2 justify-content-start"
onClick={() => changeTheme(el.label)}
>
<span className="theme-thumbnail" style={{ backgroundColor: el.value }} />
<span>{(`${el.label}`).toLocaleUpperCase()}</span>
</div>
)) : null}
</div>
</div>
<div className="p-2" style={{ width: "250px", backgroundColor: "var(--primaryBackground)" }}>
<h6 className="border-bottom p-2">Language</h6>
<div className="">
{!ERPUtils.isNullorWhiteSpace(languageList) ? languageList.map((el, index) => (
<div
key={index}
onKeyDown={(e) => {
if (ERPUtils.isKeyBoardEnterPressed(e)) {
changeLanguage(el.value);
}
}}
role="button"
tabIndex={0}
className="p-2 d-flex align-items-center font-2 justify-content-start"
onClick={() => changeLanguage(el.value)}
>
<span className="language-thumbnail">{el?.label.split("")[0]}</span>
<span>{(`${el.label}`).toLocaleUpperCase()}</span>
</div>
)) : null}
</div>
</div>
</Drawer>
{/* <ThemeSwitcherProvider defaultTheme="light" themeMap={themes}> */}
{/* <link rel="stylesheet" type="text/css" href={stylePath} /> */}
{/* </ThemeSwitcherProvider> */}
</div>
);
}
export default App;
Kindly suggest a solution for this problem ?. If I call this event listener outside App.js file it only calls once.
With each page reload the listener is added again. To fix this you should call removeAllListeners() => Promise<void> once at the beginning:
App.removeAllListeners().then(() => {
App.addListener("backButton", () => {
if (renderedScreenUIList.length === 0) {
// APPS.exitApp();
alert("exit app");
} else {
alert("previous screen");
}
});
});

React onclick update to state is not a function

I have a component A, which displays contents of a component B conditionally. Component B is contains a list of items, and when one clicks one of the items in the list, a new layout is supposed to be fired up showing details of the item. When i try to pass the props to switch to a new layout on a component B list item, i get an error toggleSearchType is not a function . Any assistance or recommendation on what i might be doing wrong will be appreciated.
My index file looks like this :
const PatientSearch: React.FC<PatientSearchProps> = ({ closePanel }) => {
const { t } = useTranslation();
const [searchType, setSearchType] = useState<SearchTypes>(SearchTypes.BASIC);
const toggleSearchType = (searchType: SearchTypes) => {
setSearchType(searchType);
};
return (
<>
<Overlay header={t('addPatientToList', 'Add patient to list')} closePanel={closePanel}>
<div className="omrs-main-content">
{searchType === SearchTypes.BASIC ? (
<BasicSearch toggleSearchType={toggleSearchType} />
) : searchType === SearchTypes.ADVANCED ? (
<PatientScheduledVisits toggleSearchType={toggleSearchType} />
) : searchType === SearchTypes.SCHEDULED_VISITS ? (
<AdvancedSearch toggleSearchType={toggleSearchType} />
) : null}
</div>
</Overlay>
</>
);
};
The searchtypes are as below :
export enum SearchTypes {
BASIC = 'basic',
ADVANCED = 'advanced',
SCHEDULED_VISITS = 'scheduled-visits'
}
My component A looks like this :
import React, { useEffect, useMemo, useState } from 'react';
interface BasicSearchProps {
toggleSearchType: (searchMode: SearchTypes) => void;
}
const BasicSearch: React.FC<BasicSearchProps> = ({ toggleSearchType }) => {
const { t } = useTranslation();
const [searchTerm, setSearchTerm] = useState('');
const [searchResults, setSearchResults] = useState<any>(null);
const customRepresentation = '';
return (
<div className={searchResults?.length ? styles.lightBackground : styles.resultsContainer}>
{searchResults?.length ? (
<div className={styles.resultsContainer}>{<SearchResults toggleSearchType={searchResults} patients={searchResults} />}</div>
) : (
<div>
<div className={styles['text-divider']}>{t('or', 'Or')}</div>
<div className={styles.buttonContainer}>
<Button
kind="ghost"
iconDescription="Advanced search"
renderIcon={Search16}
onClick={() => toggleSearchType(SearchTypes.ADVANCED)}>
{t('advancedSearch', 'Advanced search')}
</Button>
</div>
</div>
)}
</div>
);
};
export default BasicSearch;
Component B looks like this :
interface SearchResultsProps {
patients: Array<any>;
hidePanel?: any;
toggleSearchType: (searchMode: SearchTypes) => void;
}
function SearchResults({ patients, toggleSearchType }: SearchResultsProps ) {
const fhirPatients = useMemo(() => {
return patients.map((patient) => {
const preferredAddress = patient.person.addresses?.find((address) => address.preferred);
});
}, [patients]);
return (
<>
{fhirPatients.map((patient) => (
<div key={patient.id} className={styles.patientChart} onClick={() => toggleSearchType(SearchTypes.SCHEDULED_VISITS)} >
<div className={styles.container}>
<ExtensionSlot
extensionSlotName="patient-header-slot"
state={{
patient,
patientUuid: patient.id,
// onClick: onClickSearchResult,
}}
/>
</div>
</div>
))}
</>
);
}
}

How i can replace states ( arrays ) ReactJs

today I offer you a new challenge
my problem and the next
in the following code
I map objects in my database
I also map a list of items
and so basically I would like to pass my database and not the Items table
basically I want to do exactly the same thing as in the following code except that instead of using the items array, I would like to be able to use the data array which contains my database
do you have any idea how to do this?
I hope I was precise thanks to you for the help Neff
ps: Sorry for the length of the code i try to do my best to clean a little
import React, { Component } from 'react';
import { CardText, Card,Row, Col, Button } from 'reactstrap';
import axios from 'axios'
import GridLayout from 'react-grid-layout';
import SmsForm from './Sms/SMSForm'
import FruitList from './FruitList'
import './AdminPage.scss'
const UP = -1;
const DOWN = 1;
const entrypoint = process.env.REACT_APP_API_ENTRYPOINT+'/api';
class AdminPage extends Component {
constructor(props) {
super(props);
this.state = {
items: [
{ id: 1, name: "orange", bgColor: "#f9cb9c" },
{ id: 2, name: "lemon", bgColor: "#fee599" },
{ id: 3, name: "strawberry", bgColor: "#e06666" }
],
data: [],
}
handleMove = (id, direction) => {
const { items } = this.state;
const position = items.findIndex(i => i.id === id);
if (position < 0) {
throw new Error("Given item not found.");
} else if (
(direction === UP && position === 0) ||
(direction === DOWN && position === items.length - 1)
) {
return; // canot move outside of array
}
const item = items[position]; // save item for later
const newItems = items.filter(i => i.id !== id); // remove item from array
newItems.splice(position + direction, 0, item);
this.setState({ items: newItems });
};
// rest of the component
onHandleChange(event) {
const name = event.target.getAttribute('name');
this.setState({
message: { ...this.state.message, [name]: event.target.value }
});
}
getRandom = async () => {
const res = await axios.get(
entrypoint + "/alluserpls"
)
this.setState({ data: res.data })
}
componentDidMount() {
this.getRandom()
}
render() {
let datas = this.state.data.map(datass => {
const status = JSON.parse(localStorage.getItem("validated-order") || "{}")[datass.id];
return (
<div>
< Col sm="12" key={datass.id} className="wtfFuHereIsForOnlyBackGroundColorForCol12Nice">
<FruitList fruitList={this.state.items} onMove={this.handleMove} />
<GridLayout className="GridlayoutTextOnlyForGridOuiAndHeigthbecauseHeigthWasBug" layout={layout} cols={12} rowHeight={30} width={1200}>
<div key="a">
<Card body className="yoloCardBodyForbackGroundAndRaduisBorderForAdminPageWtf">
<CardText className="cardTextForAdminPageForDataName"> Commande de {datass.name}</CardText>
</Card>
</div>
</ Col>
</div>
)
})
return (
<div> <div>
<Row className="wtfHereIsAgainOnlyForRowAndMarginForAdminPageJustWtf">
<div className="isJustForOnlyPaddingOnRowForAdminPage" >
<div className="navBarGridMenuAdminPage">
<div className="thatIsOnlyForSpaceArroundOnDivAdminPage">
<CardText className="maybeColForAdminPageOuiOui"> Nouvelles commandes </CardText>
</div>
</div>
<div>
{datas}
</div>
</div>
</Row>
</div>
<div className="box">
</div>
</div>
)
}
}
export default AdminPage
here my second components
import React from "react";
const LEFT = -1;
const RIGHT = 1;
class FruitList extends React.Component {
render() {
const { fruitList, onMove } = this.props;
return (
<div style={{ display: "flex" }}>
{fruitList.map(item => (
<div
key={item.id}
style={{
backgroundColor: item.bgColor,
display: "flex"
}}
>
<div className="fruitsArrows">
<a onClick={() => onMove(item.id, LEFT)}>←</a>
</div>
<div className="fruitsId">{item.id}</div>
<div className="fruitsName">{item.name}</div>
<div className="fruitsArrows">
<a onClick={() => onMove(item.id, RIGHT)}>→</a>
</div>
</div>
))}
</div>
);
}
}
export default FruitList;
To delete particular list do like this-
pass your item(object).
<a onClick={() => onMove(item)}>→</a>
handleMove function
handleMove = (row) => {
let filtered = this.state.items.filter(item=>item.id!==row.id);
this.setState({ items: filtered});
};

Categories

Resources