I am fetching questions using an API and displaying question with dynamic radio options like this
[
{
"id": "question01",
"question": "Which of the following profiles you belongs",
"multiple": false,
"options": [
{
"id": "option01",
"title": "Buyer"
},
{
"id": "option02",
"title": "Planner"
},
{
"id": "option03",
"title": "Merchandiser"
},
{
"id": "option04",
"title": "Designer"
},
{
"id": "option05",
"title": "Analyst"
}
]
},
{
"id": "question02",
"question": "Which of the following is your responsibility?",
"multiple": true,
"options": [
{
"id": "option02_1",
"title": "Planning"
},
{
"id": "option02_2",
"title": "Design"
},
{
"id": "option02_3",
"title": "Development"
},
{
"id": "option02_4",
"title": "Testing"
}
]
},
{
"id": "question03",
"question": "What’s your level of seniority in the organization?",
"multiple": false,
"options": [
{
"id": "option03_1",
"title": "Entry Level"
},
{
"id": "option03_2",
"title": "Mid Level"
},
{
"id": "option03_3",
"title": "Senior Level"
}
]
},
{
"id": "question04",
"question": "Do you work with charts and dashboards to make data-backed decisions? ",
"multiple": false,
"options": [
{
"id": "option04_1",
"title": "Yes"
},
{
"id": "option04_2",
"title": "No"
},
{
"id": "option04_3",
"title": "Others"
}
]
}
]
I am rendering questions with options like this
<div>
{
questions && questions.length > 0 &&
questions.map((question, index) => {
return (
<div key={question.id}>
<div className='row'>
<div className='col-1'>
<h2 className='questionTitle'>Q{index 1}.</h2>
</div>
<div className='col-11 questionContainer'>
<h2 className='questionTitle'>{question.question}</h2>
</div>
</div>
</div>
<div className='optionsList'>
{
question.options && question.options.map((option, index) => {
return (
<div key={option.id} className="mb-3">
<div className='d-flex align-items-center'>
{
question.multiple ?
<div className="form-check">
<input className="form-check-input form-checkbox" type="checkbox" value={option.title} onChange={() => handleAnswerSelection(option, question.id, true)} id={option.id} />
<label className="form-check-label" htmlFor={option.id}>
{option.title}
</label>
</div>
:
<div className="form-check">
<input className="form-check-input"
type="radio"
name={question.id}
value={option.title}
onChange={() => handleAnswerSelection(option,question.id, false)}
id={option.id}
checked={answersList.length && answersList.filter(ans => ans.id === question.id) && answersList.filter(ans => ans.id === question.id)[0].values[0].title === option.title }
/>
<label className="form-check-label" htmlFor={option.id}>
{option.title}
</label>
</div>
}
</div>
</div>
)
})
}
</div>
and onChange i am handling selection like this
const handleAnswerSelection = (selectedOption, ques, hasMany) => {
if (hasMany) {
//
}
else {
const answer = {
"id": ques,
"values": [selectedOption]
}
if (answersList.length > 0 && answersList.find(ans => ans.id === ques)) {
const index = answersList.findIndex(answer => answer.id === ques);
if (index > -1) {
answersList[index].values = [selectedOption];
}
}
else {
setAnswersList([...answersList, answer]);
}
}
console.log(answersList);
}
but the problem is on changing option is not reflecting at the same time also radio button is not changing.
state variables are
const [answersList, setAnswersList] = useState([]);
please help what i am doing wrong what is the solution for this ? Thanks in advance
CodePudding user response:
const handleAnswerSelection = (selectedOption, ques, hasMany) => {
if (hasMany) {
//
}
else {
const answer = {
"id": ques,
"values": [selectedOption]
}
if (answersList.length > 0 && answersList.find(ans => ans.id === ques)) {
const index = answersList.findIndex(answer => answer.id === ques);
if (index > -1) {
let newAnswersList = [...answersList];
newAnswersList[index].values = [selectedOption];
setAnswersList(newAnswersList);
}
}
else {
setAnswersList([...answersList, answer]);
}
}
console.log(answersList);
}
It will be worked.
You should update answersList
value using setAnswersList
function.
On the following statement, the answersList
value is not changed.
answersList[index].values = [selectedOption];