I am pulling data from an API that gives me an object of items, each containing a string named correct_answer
and an array named incorrect_answers
.
I am trying to combine those values within each item, so when I do v-for
, it will loop through the answers merged together in one loop. I also want to randomize the order of those answers.
An example of what the object looks like:
"results": [ { "question": "Where was the Games of the XXII Olympiad held?", "correct_answer": "Moscow", "incorrect_answers": [ "Barcelona", "Tokyo", "Los Angeles" ] }, { "question": "What is the first weapon you acquire in Half-Life?", "correct_answer": "A crowbar", "incorrect_answers": [ "A pistol", "The H.E.V suit", "Your fists" ] }, ]
Advertisement
Answer
You could 1️⃣spread the incorrect_answers
into a new array with correct_answer
, and then 2️⃣ attach the result as a new property on the original data. Additionally, 3️⃣ you could shuffle the answers while you’re at it:
const newData = data.map(x => { const answers = [x.correct_answer, ...x.incorrect_answers] /*1️⃣*/ x.answers /*2️⃣*/ = shuffle(answers) /*3️⃣*/ return x })
This new array could be used as a computed property (e.g., named questions
) in your template:
<fieldset v-for="q in questions" :key="q.question">
const rawData = { "results": [ { "question": "Where was the Games of the XXII Olympiad held?", "correct_answer": "Moscow", "incorrect_answers": [ "Barcelona", "Tokyo", "Los Angeles" ] }, { "question": "What is the first weapon you acquire in Half-Life?", "correct_answer": "A crowbar", "incorrect_answers": [ "A pistol", "The H.E.V suit", "Your fists" ] }, ] } new Vue({ el: '#app', data() { return { rawData: rawData.results } }, computed: { questions() { return this.rawData.map(x => { const answers = [x.correct_answer, ...x.incorrect_answers] x.answers = shuffle(answers) this.$set(x, 'answer', null) // create reactive answer prop return x }) } } }) // https://stackoverflow.com/a/2450976/6277151 function shuffle(array) { let currentIndex = array.length, temporaryValue, randomIndex; // While there remain elements to shuffle... while (0 !== currentIndex) { // Pick a remaining element... randomIndex = Math.floor(Math.random() * currentIndex); currentIndex -= 1; // And swap it with the current element. temporaryValue = array[currentIndex]; array[currentIndex] = array[randomIndex]; array[randomIndex] = temporaryValue; } return array; }
<script src="https://unpkg.com/vue@2.6.10"></script> <div id="app"> <form action="#"> <fieldset v-for="(q,i) in questions" :key="q.question"> <h2>{{q.question}} {{q.answer}}</h2> <div v-for="a in q.answers" :key="a"> <label> <input type="radio" :name="i" :value="a" @change="q.answer = a"> <span>{{a}}</span> </label> </div> </fieldset> </form> </div>