I am building a survey with Vue 2, and I am trying to build and emit the answers array to a parent component called Evaluation that looks like this: https://pastebin.com/rLEUh56a
I have a component called QuestionItem.vue which is the child of Evaluation that looks like this: https://pastebin.com/RFPgKs5Q
The answers array needs to be something like this in order to be sent to the API:
answers: [
{
questionId: "6a9ad778-aacf-4e60-9610-37a767700b9f",
questionOptionIds:[
"1bc35f6c-900a-4764-84ee-23531e46e638",
],
answer: null
},
{
questionId: "d1c3f4f0-9525-4e6e-bb81-599d84b5cb02f",
questionOptionIds:[],
answer: "answered value"
},
]
Where if the question.type
is text
, range
, stars
or faces
the questionOptionIds
needs to be empty and the answer
property needs to be the answered value, but if the question.type
is radio
or check
, the answer property needs to be null and the questionOptionIds
property needs to be the answered option the user chose.
I am not sure how can I build this array from every answers that is entered in the QuestionItem.vue component.
Thanks for your time, have a nice day!
CodePudding user response:
You can't use v-model for your answers on your QuestionItem component like that:
<QuestionItem
v-for="(question, index) in questions"
:key="index"
:question="question"
:index="questionIndex"
v-model="answers"
/>
v-model is going to take your input value emitted from the child and set it to answers, which makes no sense in this case since answers is an array of each answer, rather than a singular answer.
You're going to need to have a custom event handler in your parent component. Something like this:
// in Evaluation.vue methods
answerChanged(answer) {
// remove this answer if it's already in the array
answers = answers.filter(a=>a.questionId != answer.questionId);
// add the submitted answer
answers.push(answer);
}
then instead of v-model, use an event handler:
<QuestionItem
v-for="(question, index) in questions"
:key="index"
:question="question"
:index="questionIndex"
@input="answerChanged" //bind the event handler
/>
lastly, you'll need to add the questionId to the value that you're emitting. This is an approximation, you might need to adapt this to fit the exact format you're looking for:
watch: {
questionValue(newValue) {
// emit the value that we want for a single answer in our parent answers array
this.$emit('input', {
questionId: question.id,
questionOptionIds:question.options,
answer: newValue
})
},
},