1

I've got this quiz app.

I've got a question and 4 answer each, there are 10 questions and each time they are shown randomly.

I've got a button that when it's triggered it should delete 2 of the 4 displayed answers, always keeping the correct answer in obviously.

So I need to delete two elements from an object cause my questions array is formed by ten of these objects:

{
  domanda: "Quando è iniziata la prima guerra mondiale?",
  risposte: { a: "1993", b: "1910", c: "1915", d: "1879" },
  rispostaCorretta: "c",
},

So considering this question, when I click on that button it should delete 2 answers (a, b or d) and let the c answer always in cause it's the correct one.

Here's the function that should do the job:

getHalf(obj) {
      console.log(obj)
      for(var k in obj.risposte) {
        console.log(k)
        if(k != obj.rispostaCorretta) {
          this.$delete(k, obj.risposte)
        }
      }
    }

At the moment it gives me these errors:

Cannot delete reactive property on undefined, null, or primitive value: a
Cannot delete reactive property on undefined, null, or primitive value: b
Cannot delete reactive property on undefined, null, or primitive value: c

This is the current object:

{
  domanda: "Chi era il frontman dei Queen?",
  risposte: {
   a: "Zlatan",
   b: "Er Freddo",
   c: "Otello Lupacchini",
   d: "Freddy Mercury",
  },
  rispostaCorretta: "d",
},

The d is the correct answer so at least that is working, now it should be 2 of the others and not 3.

This is the button, i'm passing in the current question each time

<button @click="getHalf(domande[domandaCorrente])">50/50</button>

I tried with Vue.delete(...) or this.$delete('a', obj) but it didn't work, it give me back this error most of the time: Cannot delete reactive property on undefined, null, or primitive value: a

How can I solve this?? Help me if you can please.

I leave here the whole Vue template

<template>
  <div class="question">
    <div class="q" v-if="domandaCorrente < domande.length && !finish">
      <h2 class="border">{{ domande[domandaCorrente].domanda }}</h2>

      <!-- <Answer @selectAnswer="setAnswer" :domande="domande" /> -->
      <div class="answer">
        <label
          class="answer-label border hide"
          :for="index"
          v-for="(risposta, index) in domande[domandaCorrente].risposte"
          :key="index"
          :class="{
            hover: domandaScelta == '',
            'bg-red': domandaScelta == index,
            'bg-green':
              index == domande[domandaCorrente].rispostaCorretta &&
              domandaScelta != '',
          }"
        >
          <input
            type="radio"
            :checked="index == selected"
            :name="index"
            :id="index"
            class="hidden"
            :value="index"
            @change="select($event)"
          />

          <h4 class="index">{{ index }}</h4>
          <h4 class="actual-answer">{{ risposta }}</h4>
        </label>
        <button @click="getHalf(domande[domandaCorrente])">50/50</button>
        <div
          v-show="
            domandaScelta != '' &&
            domandaCorrente < domande.length - 1 &&
            !finish
          "
          class="button"
        >
          <button v-show="!endGame" @click="nextQuestion()">
            Vai alla domanda da {{ nextPrice | toCurrency }} &euro;
          </button>
          <h4 class="wrong" v-show="endGame">Hai Sbagliato!</h4>
        </div>
        <div
          v-show="
            domandaScelta != '' &&
            domandaCorrente == domande.length - 1 &&
            !finish
          "
          class="button"
        >
          <button @click="showResult()">Finish</button>
        </div>
      </div>
    </div>
    <div v-else-if="finish || domandaCorrente == domande.length">
      <div class="end">
        <!-- <h2>
          Correct Answers: <span class="t-green">{{ correct }}</span>
        </h2> -->
        <h2 v-show="domandaCorrente != domande.length">Ti sei fermato alla domanda {{ domandaCorrente + 1 }}</h2>
        <h2 v-show="domandaCorrente == domande.length" >Complimenti! Hai completato la scalata!</h2>
        <h5 style="margin: 30px 0">Torni a casa con</h5>
        <h2 style="color: gold; font-size: 3rem">
          {{ finalPrice | toCurrency }} &euro;
        </h2>
        <button class="reload" @click="reloadQuiz()">
          Inizia di nuovo la scalata!
        </button>
      </div>
    </div>
  </div>
</template>

<script>
import Vue from "vue";
export default {
  name: "Question",
  data() {
    return {
      //   random: 0,
      half: false,
      domandaCorrente: 0,
      correct: 0,
      nextPrice: 0,
      wrong: 0,
      endGame: false,
      domandaScelta: "",
      selected: false,
      finish: false,
      gift: [1000, 2000, 3000, 5000, 10000, 15000, 25000, 40000, 50000, 100000],
      finalPrice: 0,
      domande: [
        {
          domanda: "Quante champions ha vinto il Milan?",
          risposte: { a: "2", b: "5", c: "7", d: "10" },
          rispostaCorretta: "c",
        },
        {
          domanda: "La capitale della Romania?",
          risposte: { a: "Bucarest", b: "Milano", c: "Berlino", d: "Oslo" },
          rispostaCorretta: "a",
        },
        {
          domanda: "Chi ha scoperto l'America?",
          risposte: {
            a: "Cristoforo Colombo",
            b: "Carlo Pellegatti",
            c: "216",
            d: "Amerigo Vespucci",
          },
          rispostaCorretta: "a",
        },
        {
          domanda: "Quando è iniziata la prima guerra mondiale?",
          risposte: { a: "1993", b: "1910", c: "1915", d: "1879" },
          rispostaCorretta: "c",
        },
        {
          domanda: "Chi era il frontman dei Queen?",
          risposte: {
            a: "Zlatan",
            b: "Er Freddo",
            c: "Otello Lupacchini",
            d: "Freddy Mercury",
          },
          rispostaCorretta: "d",
        },
        {
          domanda: "A quale temperatura bolle l'acqua?",
          risposte: { a: "10°", b: "5°", c: "70°", d: "100°" },
          rispostaCorretta: "d",
        },
        {
          domanda: "Chi ha vinto gli europei nel 2021",
          risposte: { a: "Spagna", b: "Germania", c: "Italia", d: "Danimarca" },
          rispostaCorretta: "c",
        },
        {
          domanda: "Quale di queste è una funzione?",
          risposte: {
            a: "let item = 23",
            b: "function getItem() ...",
            c: "return",
            d: "string.join()",
          },
          rispostaCorretta: "b",
        },
        {
          domanda: "Come si passano dati ad un componente figlio in Vue?",
          risposte: { a: "Props", b: "Emit", c: "Componenti", d: "Altro" },
          rispostaCorretta: "a",
        },
        {
          domanda: "Quante champions ha vinto la Juve?",
          risposte: { a: "2", b: "5", c: "7", d: "10" },
          rispostaCorretta: "a",
        },
      ],
    };
  },

  methods: {
    select(e) {
      this.selected = e.target.value;
      this.domandaScelta = e.target.value;
      //   console.log(this.domandaScelta);
      //   console.log(this.domandaCorrente);
      if (
        this.domandaScelta ==
        this.domande[this.domandaCorrente].rispostaCorretta
      ) {
        this.correct++;
        this.finalPrice = this.gift[this.domandaCorrente];
        this.nextPrice = this.gift[this.domandaCorrente + 1];
        this.finish = false;
      } else {
        // this.reload();
        this.endGame = true;
        setTimeout(() => {
          this.finish = true;
        }, 1500);
        // this.wrong++
      }
    },

    shuffleVueArray(array) {
      for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        const temp = array[i];
        Vue.set(array, i, array[j]);
        Vue.set(array, j, temp);
      }
    },

    nextQuestion() {
      this.domandaScelta = "";
      this.selected = false;
      this.domandaCorrente++;
    },

    showResult() {
      this.domandaCorrente++;
    },

    reloadQuiz() {
      location.reload();
    },

    toCurrency() {
      Vue.filter("toCurrency", function (value) {
        if (typeof value !== "number") {
          return value;
        }
        var formatter = new Intl.NumberFormat("en-US", {
          style: "currency",
          currency: "USD",
          minimumFractionDigits: 0,
        });
        return formatter.format(value);
      });
    },

    getHalf(obj) {
      console.log(obj)
      for(var k in obj.risposte) {
        console.log(k)
        if(k != obj.rispostaCorretta) {
          this.$delete(k, obj.risposte)
        }
      }
    }

    
  },

  created() {
    this.shuffleVueArray(this.domande);
    this.toCurrency();
  },
};
</script>
2
  • what is domandaCorrente? Commented Sep 24, 2021 at 8:16
  • It's a variable index in the data, starts at 0 and each time I click next domandaCorrente goes 1 (2nd question) and so on. However, I've edited the question with the whole Vue template. Commented Sep 24, 2021 at 8:18

2 Answers 2

1

Try this way to remove 2 answers :

getHalf(obj) {
  let nr = 0
  const removeProperty = (propKey, { [propKey]: propValue, ...rest }) => rest;
  for(var k in obj.risposte) {
    if (nr < 2) {
      if(k != obj.rispostaCorretta) {
        obj.risposte = removeProperty(k, obj.risposte);
         nr++
      }
    } else return
  }
},

new Vue({
  el: '#demo',
  name: "Question",
  data() {
    return {
      //   random: 0,
      half: false,
      domandaCorrente: 0,
      correct: 0,
      nextPrice: 0,
      wrong: 0,
      endGame: false,
      domandaScelta: "",
      selected: false,
      finish: false,
      gift: [1000, 2000, 3000, 5000, 10000, 15000, 25000, 40000, 50000, 100000],
      finalPrice: 0,
      domande: [
        {
          domanda: "Quante champions ha vinto il Milan?",
          risposte: { a: "2", b: "5", c: "7", d: "10" },
          rispostaCorretta: "c",
        },
        {
          domanda: "La capitale della Romania?",
          risposte: { a: "Bucarest", b: "Milano", c: "Berlino", d: "Oslo" },
          rispostaCorretta: "a",
        },
        {
          domanda: "Chi ha scoperto l'America?",
          risposte: {
            a: "Cristoforo Colombo",
            b: "Carlo Pellegatti",
            c: "216",
            d: "Amerigo Vespucci",
          },
          rispostaCorretta: "a",
        },
        {
          domanda: "Quando è iniziata la prima guerra mondiale?",
          risposte: { a: "1993", b: "1910", c: "1915", d: "1879" },
          rispostaCorretta: "c",
        },
        {
          domanda: "Chi era il frontman dei Queen?",
          risposte: {
            a: "Zlatan",
            b: "Er Freddo",
            c: "Otello Lupacchini",
            d: "Freddy Mercury",
          },
          rispostaCorretta: "d",
        },
        {
          domanda: "A quale temperatura bolle l'acqua?",
          risposte: { a: "10°", b: "5°", c: "70°", d: "100°" },
          rispostaCorretta: "d",
        },
        {
          domanda: "Chi ha vinto gli europei nel 2021",
          risposte: { a: "Spagna", b: "Germania", c: "Italia", d: "Danimarca" },
          rispostaCorretta: "c",
        },
        {
          domanda: "Quale di queste è una funzione?",
          risposte: {
            a: "let item = 23",
            b: "function getItem() ...",
            c: "return",
            d: "string.join()",
          },
          rispostaCorretta: "b",
        },
        {
          domanda: "Come si passano dati ad un componente figlio in Vue?",
          risposte: { a: "Props", b: "Emit", c: "Componenti", d: "Altro" },
          rispostaCorretta: "a",
        },
        {
          domanda: "Quante champions ha vinto la Juve?",
          risposte: { a: "2", b: "5", c: "7", d: "10" },
          rispostaCorretta: "a",
        },
      ],
    };
  },

  methods: {
    select(e) {
      this.selected = e.target.value;
      this.domandaScelta = e.target.value;
      //   console.log(this.domandaScelta);
      //   console.log(this.domandaCorrente);
      if (
        this.domandaScelta ==
        this.domande[this.domandaCorrente].rispostaCorretta
      ) {
        this.correct++;
        this.finalPrice = this.gift[this.domandaCorrente];
        this.nextPrice = this.gift[this.domandaCorrente + 1];
        this.finish = false;
      } else {
        // this.reload();
        this.endGame = true;
        setTimeout(() => {
          this.finish = true;
        }, 1500);
        // this.wrong++
      }
    },

    shuffleVueArray(array) {
      for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        const temp = array[i];
        Vue.set(array, i, array[j]);
        Vue.set(array, j, temp);
      }
    },

    nextQuestion() {
      this.domandaScelta = "";
      this.selected = false;
      this.domandaCorrente++;
    },

    showResult() {
      this.domandaCorrente++;
    },

    reloadQuiz() {
      location.reload();
    },

    toCurrency() {
      Vue.filter("toCurrency", function (value) {
        if (typeof value !== "number") {
          return value;
        }
        var formatter = new Intl.NumberFormat("en-US", {
          style: "currency",
          currency: "USD",
          minimumFractionDigits: 0,
        });
        return formatter.format(value);
      });
    },

    getHalf(obj) {
      let nr = 0
      const removeProperty = (propKey, { [propKey]: propValue, ...rest }) => rest;
      for(var k in obj.risposte) {
        if (nr < 2) {
          if(k != obj.rispostaCorretta) {
            obj.risposte = removeProperty(k, obj.risposte);
             nr++
          }
        } else return
      }
    },
    

    
  },

  created() {
    this.shuffleVueArray(this.domande);
    this.toCurrency();
  },
});
Vue.config.productionTip = false
Vue.config.devtools = false
.answer {
  display: flex;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <div class="question">
    <div class="q" v-if="domandaCorrente < domande.length && !finish">
      <h2 class="border">{{ domande[domandaCorrente].domanda }}</h2>

      <!-- <Answer @selectAnswer="setAnswer" :domande="domande" /> -->
      <div class="answer">
        <label
          class="answer-label border hide"
          :for="index"
          v-for="(risposta, index) in domande[domandaCorrente].risposte"
          :key="index"
          :class="{
            hover: domandaScelta == '',
            'bg-red': domandaScelta == index,
            'bg-green':
              index == domande[domandaCorrente].rispostaCorretta &&
              domandaScelta != '',
          }"
        >
          <input
            type="radio"
            :checked="index == selected"
            :name="index"
            :id="index"
            class="hidden"
            :value="index"
            @change="select($event)"
          />

          <h4 class="index">{{ index }}</h4>
          <h4 class="actual-answer">{{ risposta }}</h4>
        </label>
        <button @click="getHalf(domande[domandaCorrente])">50/50</button>
        <div
          v-show="
            domandaScelta != '' &&
            domandaCorrente < domande.length - 1 &&
            !finish
          "
          class="button"
        >
          <button v-show="!endGame" @click="nextQuestion()">
            Vai alla domanda da {{ nextPrice | toCurrency }} &euro;
          </button>
          <h4 class="wrong" v-show="endGame">Hai Sbagliato!</h4>
        </div>
        <div
          v-show="
            domandaScelta != '' &&
            domandaCorrente == domande.length - 1 &&
            !finish
          "
          class="button"
        >
          <button @click="showResult()">Finish</button>
        </div>
      </div>
    </div>
    <div v-else-if="finish || domandaCorrente == domande.length">
      <div class="end">
        <!-- <h2>
          Correct Answers: <span class="t-green">{{ correct }}</span>
        </h2> -->
        <h2 v-show="domandaCorrente != domande.length">Ti sei fermato alla domanda {{ domandaCorrente + 1 }}</h2>
        <h2 v-show="domandaCorrente == domande.length" >Complimenti! Hai completato la scalata!</h2>
        <h5 style="margin: 30px 0">Torni a casa con</h5>
        <h2 style="color: gold; font-size: 3rem">
          {{ finalPrice | toCurrency }} &euro;
        </h2>
        <button class="reload" @click="reloadQuiz()">
          Inizia di nuovo la scalata!
        </button>
      </div>
    </div>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

3 Comments

It works! But sometimes it deletes only one answer, why?
Sorry mate, my bad, check now pls
Perfect, now it's working! Thanks Nikola!
0

Your question is a little complex, but I think I got your main question, you want to remove 2 answers from 4 answers.

If the question object comes from props, you should not mutate it directly, you have to create a clone from it, then can mutate and use the cloned question.

In this example, I watch the prop value, whenever there is a new value I put it inside a tempQuestion, and then I can mutate the tempQuestion by a method.

// inside vue component
{

props: {
     question: Object,
},

data() {
     return {
          tempQuestion: null,
     }
},

watch: {
     question: {
      deep: true,
      immediate: true,
      handler(newValue) {
          this.tempQuestion = newValue; 
      },
     }
},

methods: {
     removeAnswers() {
          delete this.tempQuestion.risposte.a
     }
}

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.