Issues with pushing nested object. Vue Warnings
-
Hello,
I am creating a form that consists of nested objects (see the object structure below). I want to add questions (from any question’s add button if possible) and for each question, as many answers as possible.
I encounter issues when I click on the add button. I tried to add a question by clicking on the add button of the initial question (q0): it allows me to create another question (q1) and more. However, if I want to create a question by clicking on (q1), I get the following errors in the console.[Vue warn]: Error in event handler for "click": "TypeError: Cannot read property 'questions' of undefined"
I also tried the following with
this.forms[index].questions[index].answerChoices.push
I get the following warning:
[Vue warn]: Error in event handler for "click": "TypeError: Cannot read property 'questions' of undefined"
I have the following setup in template and script.<template> <q-page> <q-card class="bg-cyan-2 q-ma-xl"> <q-card-main> <div v-for="form in forms" :key="form.id"> <q-field class="q-mb-sm" label="Form Title: " helper="Please enter the title of the question."> <q-input v-model="form.name" type="text" clearable /> </q-field> <q-card-separator class="q-mb-md q-mt-xl"/> <div v-for="(question, index) in form.questions" :key="question.id"> <q-btn class="q-mb-md" round size="sm" color="amber" icon="add" @click="addRowQuestions(index)" /> <q-field class="q-mb-sm" label="Question Title: " > <q-input v-model="question.text" /> </q-field> <q-card-separator class="q-mb-md q-mt-xl"/> <div v-for="(answerChoice, index) in question.answerChoices" :key="answerChoice.id"> <q-btn class="q-mb-md" round size="sm" color="green" icon="add" @click="addAnswers(index)" /> <q-field class="q-mb-sm" label="Answer ID: "> <q-input v-model="answerChoice.answerId" type="number" clearable /> </q-field> <q-card-separator class="q-mb-md q-mt-xl"/> </div> </div> </div> </q-card-main> </q-card> </q-page> </template>
<script> export default { data () { return { forms: [ { name: '', questions: [ { text: '', answerChoices: [ { answerId: '' } ] } ] } ] } }, methods: { addRowQuestions (index) { this.forms[index].questions.push({ text: '', answerChoices: [] }) }, addAnswers (index) { this.forms[index].questions[index].answerChoices.push({ answerId: '' }) } } } </script>
I’ve looked at various sites but am stuck on this.
I’ve looked at something like this but don’t know how to get and send the respective indexes.this.forms[formIndex].questions[questionIndex].answerChoices.push
Any suggestions please to resolve the warnings and correct/improve this form?
-
<template> <q-page> <q-card class="bg-cyan-2 q-ma-xl"> <q-card-main> <div v-for="(form, formIndex) in forms" :key="form.id"> <q-field class="q-mb-sm" label="Form Title: " helper="Please enter the title of the question."> <q-input v-model="form.name" type="text" clearable /> </q-field> <q-card-separator class="q-mb-md q-mt-xl"/> <div v-for="(question, questionIndex) in form.questions" :key="question.id"> <q-btn class="q-mb-md" round size="sm" color="amber" icon="add" @click="addRowQuestions(formIndex)" /> <q-field class="q-mb-sm" label="Question Title: " > <q-input v-model="question.text" /> </q-field> <q-card-separator class="q-mb-md q-mt-xl"/> <div v-for="(answerChoice, answerIndex) in question.answerChoices" :key="answerChoice.id"> <q-btn class="q-mb-md" round size="sm" color="green" icon="add" @click="addAnswers(formIndex, questionIndex)" /> <q-field class="q-mb-sm" label="Answer ID: "> <q-input v-model="answerChoice.answerId" type="number" clearable /> </q-field> <q-card-separator class="q-mb-md q-mt-xl"/> </div> </div> </div> </q-card-main> </q-card> </q-page> </template>
and
addAnswers (formIndex, questionIndex) { this.forms[formIndex].questions[questionIndex].answerChoices.push({ answerId: '' }) }
Hope that helps! At least it should get you started.
-
Thanks @Hawkeye64 for your help. I’ve been able to follow your suggestion and got it to work.
My modified working code is below for anyone interested. Note that I have added 2 extra buttons to allow the removal of questions and answers.<div v-for="(form, fIndex) in forms" :key="form.id"> <q-field class="q-mb-sm" label="Form Title: " helper="Please enter the title of the form."> <q-input v-model="form.name" type="text" clearable /> </q-field> <q-card-separator class="q-mb-md q-mt-xl"/> <div v-for="(question, qIndex) in form.questions" :key="question.id"> <q-btn class="q-mb-md" round size="sm" color="amber" icon="add" @click="addRowQuestions(fIndex)" /> <q-btn class="vertical-top" v-show="qIndex !==0" round size="sm" color="blue" icon="remove" @click="remRowQs(fIndex)" /> <q-field class="q-mb-sm" label="Question Title: " > <q-input v-model="question.text" /> </q-field> <q-card-separator class="q-mb-md q-mt-xl"/> <div v-for="(answerChoice, aIndex) in question.answerChoices" :key="answerChoice.id"> <q-btn class="q-mb-md" round size="sm" color="green" icon="add" @click="addAnswers(fIndex, qIndex)" /> <q-btn class="vertical-top" v-show="aIndex !==0" round size="sm" color="negative" icon="remove" @click="remRowAns(fIndex, qIndex)" /> <q-field class="q-mb-sm" label="Answer ID: "> <q-input v-model="answerChoice.answerId" type="number" clearable /> </q-field> <q-card-separator class="q-mb-md q-mt-xl"/> </div> </div> </div>
methods: { addRowQuestions (fIndex) { this.forms[fIndex].questions.push({ qtext: '', answerChoices: [ { answerId: '' } ] }) }, addAnswers (fIndex, qIndex) { this.forms[fIndex].questions[qIndex].answerChoices.push({ answerId: '' }) }, remRowQs (fIndex) { this.forms[fIndex].questions.splice(fIndex, 1) }, remRowAns (fIndex, qIndex) { this.forms[fIndex].questions[qIndex].answerChoices.splice(qIndex, 1) } } }