I have this object called Quiz, I can edit the primary Quiz properties fine.
A quiz has: Title, timeLimit, value and QuestionList - Made up of Question objects.
Each question has 4 properties: Question (string), value, explanation and AnswerList
Each answer has 2 properties: content and correct
I am able to modify the base quiz properties (title, time limit and value) without issue. I am also able to display each question and pass it to the modal where it will populate the fields, including the answers too.
However the issue occurs when trying to modify a field (both within question or answer) I get presented the following error:
TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))
Im guessing this is because of the onChange function Im using on each input, however these do work for editing the Quiz?
The same issue occurs when adding a new question instance too.
I have tried to include all minimum code to run
code:
import 'bootstrap/dist/css/bootstrap.min.css';
import React, {useState, useEffect} from 'react';
import { Modal, Form, Button } from 'react-bootstrap';
export default function EditQuiz(props) {
const [quiz, setQuiz] = useState({title:"example", timeLimit:300, value:200})
const [questionList, setQuestionList]=useState( [
{ id: 1, question : "question1", value:5, explaination : "answer1",
answers: [ {content: "aaa", correct: true},{content: "bbb", correct: false},{content: "ccc", correct: false},{content: "ddd", correct: false}]
} ,
{ id: 2, question : "question2", value:10, explaination : "answer1",
answers: [ {content: "eee", correct: true},{content: "fff", correct: false},{content: "ggg", correct: false},{content: "hhhh", correct: false} ]
}
])
const [submitQuiz, setSubmitQuiz] = useState(false);
const [executedSet, setExecutedSet] = useState(false);
const [missingParentData, setMissingParentData] = useState();
useEffect(() => {
if (props.location.state){
setQuiz(props.location.state)
setQuestionList(props.location.state.questions)
setExecutedSet(true)
}
else{
setMissingParentData(true)
}
console.log(quiz)
},[])
const addQuestionButton = () => {
setQuestion({question: "", value:0, explaination: "", answers : [ {content: "", correct: false},{content: "", correct: false},{content: "", correct: false},{content: "", correct: false} ] })
setShow(true)
};
const editQuestionButton = (question) =>{
console.log(question)
setQuestion(question)
setShow(true)
}
const printQuizButton = () => {
console.log(quiz)
};
const [value, setValue] = useState(0);
const [show, setShow] = useState(false);
const [correct, setCorrect] = useState(false);
const [explaination, setExplaination] = useState("");
const [question, setQuestion]=useState('')
const [dropdown, setDropdown]=useState("")
return (
<div className='page'>
<br/>
<h1>Quiz input / Edit Page</h1>
<br/><br/><br/>
<h2>Quiz</h2>
<form action="">
<label htmlFor="Title">Title</label>
<br/>
<input type="text" id="title" name="title" value={ quiz ? quiz.title : ''} onChange={(e)=>setQuiz({...quiz, title: e.target.value})}/>
<br/>
<label htmlFor="Time-limit">Time limit (seconds)</label>
<br/>
<input type="number" id="Time-limit" name="Time-limit" value={quiz ? quiz.timeLimit : ''} onChange={(e)=>setQuiz({...quiz, timeLimit: e.target.value})}/>
<br/>
<label htmlFor="Value">Value</label>
<br/>
<input type="number" id="Value" name="Value" value={quiz ? quiz.value : ''} onChange={(e)=>setQuiz({...quiz, value: e.target.value})}/>
<br/><br/>
<input type="submit" className="Send-Message-CTA shadow" value="Submit Quiz"/>
</form>
<h2>Questions</h2>
<button onClick={()=> printQuizButton()}>print Quiz</button>
<button onClick={()=> addQuestionButton()}>Add Question</button>
{questionList.map((question, index)=>(
<div key={index}>
ID: {question.id} Question: {question.question}
<br/>
<button onClick={()=> editQuestionButton(question)}>Edit Question</button>
<br/>
<br/>
</div>
))}
<Modal show={show} backdrop="static" keyboard={false} state={question ? question : ""}>
<Modal.Header>
<Modal.Title>Adding Question Form</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<div className="form-group">
<label htmlFor="question">Question</label>
<input value={question ? question.question: ''} onChange={(e)=>setQuestion(...question, e.target.value)} type="text"
className="form-control stuff" id="question" placeholder="Enter question name" required/>
</div>
<div className="form-group">
<label htmlFor="value">Value</label>
<input value={question ? question.value: ''} onChange={(e)=>setQuestion(...question, e.target.value)} type="number" className="form-control stuff" id="value" required/>
</div>
<div className="form-group">
<label htmlFor="explaination">Explaination</label>
<input value={question ? question.explaination: ''} onChange={(e)=>setQuestion(...question, e.target.value)} type="text"
className="form-control stuff" id="explaination" placeholder="Enter Correct Explaination" required/>
</div>
<br/>
You may enter up to 4 answers below:
<br/>
(Leave blank if un-wanted, requires atleast 2)
<br/><br/>
{ question.answers ? question.answers.map((answer, index)=>(
<div key={index}>
<div className="form-group">
<label htmlFor="explaination">Answer {index 1}</label>
{/* <input onChange={ (e) => setAnswers(prevAnswers => { prevAnswers[index] = e.target.value; return prevAnswers; })} value={ answer ? answer.content : ''} type="text" className="form-control stuff" id="explaination" placeholder="Enter answer display words" required/> */}
<input onChange={ (e) => setQuestion ( ...question, e.target.value )} value={ answer ? answer.content : ''} type="text"
className="form-control stuff" id="explaination" placeholder="Enter answer display words" required/>
</div>
</div>
)) : <br/> }
</Form>
</Modal.Body>
<Modal.Footer>
<Button type="submit" className="btn btn-dark" onClick={()=> setShow(false)}> Close </Button>
</Modal>
</div>);
}
CodePudding user response:
setQuestion(...question, e.target.value)
should be
setQuestion({...question, explanation: e.target.value})
