Home > Net >  Create an aswers array from a child component then emit this array to the parent in Vue.js 2
Create an aswers array from a child component then emit this array to the parent in Vue.js 2

Time:12-30

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
        })
    },
},
  • Related