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:
JavaScript
x
21
21
1
"results": [
2
{
3
"question": "Where was the Games of the XXII Olympiad held?",
4
"correct_answer": "Moscow",
5
"incorrect_answers": [
6
"Barcelona",
7
"Tokyo",
8
"Los Angeles"
9
]
10
},
11
{
12
"question": "What is the first weapon you acquire in Half-Life?",
13
"correct_answer": "A crowbar",
14
"incorrect_answers": [
15
"A pistol",
16
"The H.E.V suit",
17
"Your fists"
18
]
19
},
20
]
21
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:
JavaScript
1
6
1
const newData = data.map(x => {
2
const answers = [x.correct_answer, x.incorrect_answers] /*1️⃣*/
3
x.answers /*2️⃣*/ = shuffle(answers) /*3️⃣*/
4
return x
5
})
6
This new array could be used as a computed property (e.g., named questions
) in your template:
JavaScript
1
2
1
<fieldset v-for="q in questions" :key="q.question">
2
JavaScript
1
61
61
1
const rawData = {
2
"results": [
3
{
4
"question": "Where was the Games of the XXII Olympiad held?",
5
"correct_answer": "Moscow",
6
"incorrect_answers": [
7
"Barcelona",
8
"Tokyo",
9
"Los Angeles"
10
]
11
},
12
{
13
"question": "What is the first weapon you acquire in Half-Life?",
14
"correct_answer": "A crowbar",
15
"incorrect_answers": [
16
"A pistol",
17
"The H.E.V suit",
18
"Your fists"
19
]
20
},
21
]
22
}
23
24
new Vue({
25
el: '#app',
26
data() {
27
return {
28
rawData: rawData.results
29
}
30
},
31
computed: {
32
questions() {
33
return this.rawData.map(x => {
34
const answers = [x.correct_answer, x.incorrect_answers]
35
x.answers = shuffle(answers)
36
this.$set(x, 'answer', null) // create reactive answer prop
37
return x
38
})
39
}
40
}
41
})
42
43
// https://stackoverflow.com/a/2450976/6277151
44
function shuffle(array) {
45
let currentIndex = array.length, temporaryValue, randomIndex;
46
47
// While there remain elements to shuffle...
48
while (0 !== currentIndex) {
49
50
// Pick a remaining element...
51
randomIndex = Math.floor(Math.random() * currentIndex);
52
currentIndex -= 1;
53
54
// And swap it with the current element.
55
temporaryValue = array[currentIndex];
56
array[currentIndex] = array[randomIndex];
57
array[randomIndex] = temporaryValue;
58
}
59
60
return array;
61
}
JavaScript
1
16
16
1
<script src="https://unpkg.com/vue@2.6.10"></script>
2
3
<div id="app">
4
<form action="#">
5
<fieldset v-for="(q,i) in questions" :key="q.question">
6
<h2>{{q.question}} {{q.answer}}</h2>
7
8
<div v-for="a in q.answers" :key="a">
9
<label>
10
<input type="radio" :name="i" :value="a" @change="q.answer = a">
11
<span>{{a}}</span>
12
</label>
13
</div>
14
</fieldset>
15
</form>
16
</div>