How to pass function to V-on

Viewed 23

I'm stuck with this error when I try to press Next to switch question & answer. I'm currently using Vue2. What should I change if i want to use nextbtn function to switch question & answer at the same time. Error:"[Vue warn]: Error in v-on handler: 'ReferenceError: nextBtn is not defined'

found in

---> "

HTML

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<div id="app1">
  <display-question></display-question>
</div>

JS

Vue.component('display-question',{
  data: function(){
    return{
      counter: 0,
      currentQuestion: 0,
      answered: 0,
      showWrongQuestion: false,
      wrongQuestions: [],
      temp: [],
      wrongAnswers: 0,
      correctAnswers: 0,
    message: "Enter your answer here",
    WhatAnswer: "default",
   questions: [
            {
            question: 'What is the capital of Ukrain ?',
            answer: [
                'Kyiv',
                '   Kabul',
                '   Buenos Aires',
                '   Praia'
            ],
            correct_answer: 0,
            selected: null,
            sense: 0
            },
            {
            question: 'When was Queen Elizabeth II death ?',
            answer: [
                '11/09/2022',
                '08/09/2022',
                '12/08/2022',
                '07/09/2022'
            ],
            correct_answer: 1,
            selected: null,
            sense: 0
            },
         {
            question: 'How many bones are there in human body?',
            answer: [
                '206',
                '186',
                '209',
                '190'
            ],
            correct_answer: 0,
            selected: null,
            sense: 0
            },
         {
            question: 'Who were the 30th president of ?',
            answer: [
                'Julia Eileen Gillard',
                'John Winston Howard ',
                ' Scott John Morrison ',
                'Anthony Albanese,'
            ],
            correct_answer: 2,
            selected: null,
            sense: 0
            },
         {
            question: 'What is the biggest continent?',
            answer: [
                'Oceania',
                'Europe',
                'Asia',
                'Africa'
            ],
            correct_answer: 2,
            selected: null,
            sense: 0
            }
        ],
  }},
  
  methods: {
    backBtn:function () {
      if (this.question > 0) {
        this.question = this.question - 1;
      }
    },
    nextBtn: function(){
      this.answered < this.questions.length ? this.answered++ : ''; 
     if(!nextBtn.hasAttribute('disabled') && this.currentQuestion < (questionsLength -1)) {    
        this.currentQuestion++; //I think error happen here
        
        answers.forEach(answer => {
          answer.classList.contains('selected') ? answer.classList.remove('selected') : '';
        });
    nextBtn.setAttribute('disabled', '');   
      } 
      else if(this.currentQuestion >= (questionsLength -1)) {
        
        this.questions.forEach( (question) => {
          if(question.selected == question.correct_answer && question.sense ==0) {
            
            this.correctAnswers++;
            question.sense = 1;
            
          } else if(question.selected != question.correct_answer && question.sense ==0) {
            
            this.wrongAnswers++;
            question.sense = 1;
            let temp = {};
            temp.answers = question.answers;
            temp.question = question.question;
            temp.correct_answer = question.correct_answer;
            temp.selected = question.selected;
            
            this.wrongQuestions.push(temp);
          }
        });
    result.classList.add('active');
        question.classList.add('blur');
      } 
    },
   
     calculateResult: (questions) => {
      var correct;
      for(var i=0; i< questions.length; i++) {
        this.questions[i].selected == questions[i].correct ?  correct++ : '';
      }
return (correct / questions.length) * 100;
    },
    selectAnswer: function(a) {
      var choice = a.currentTarget,
          answers = document.querySelectorAll('.answers span'),
          nextBtn = document.querySelector('.next-btn');
      
      answers.forEach(answer => {
        answer.classList.contains('selected') ? answer.classList.remove('selected') : '';
      });
      
      choice.classList.add('selected');
      
      this.questions[this.currentQuestion].selected = choice.dataset.index;
 nextBtn.removeAttribute('disabled');
      
    },
  },       
  mounted() {
    var nextBtn = this.$el.querySelector('.next-btn'),
        wrongAnswersBtn = this.$el.querySelector('.show-wrong-ones'),
        backBtn = this.$el.querySelector('.back-Btn'),
        answers = this.$el.querySelectorAll('.answers span'),
        questionsLength = this.questions.length,
        result = this.$el.querySelector('.result'),
        question = this.$el.querySelector('.question'),
        closeResult = this.$el.querySelector('.result button.close'),
        wrongQuestions = this.$el.querySelector('.wrong-questions'),
        showMyResults = this.$el.querySelector('#return-to-result'); 
 
    
},
  template: '<div><div v-if="counter < questions.length"> <h2>{{questions[currentQuestion].question }}</h2></br> <span class=answer v-for="(answer, index) in questions[currentQuestion].answer" :key="index" v-bind:data-index="index" @click="selectAnswer">{{ answer }}</span><p><button class="backBtn" v-on:click="backBtn">BACK</button> <button class="next-btn" v-on:click="nextBtn" disabled > {{ currentQuestion < (questions.length -1) ? "Next" : "Result!" }} </button></p> </div> <div class="result"><div class="success"></div></div></div>',
})
var test1 = new Vue({
  el: "#app1",
  data: {
  },
});


1 Answers

It seems like what's undefined is not the nextBtn method, but the nextBtn variable that you referenced inside the nextBtn method (from this line if(!nextBtn.hasAttribute('disabled') && this.currentQuestion < (questionsLength -1)) {), on mounted you initialized some variables, you should declare those variables first on data(), then initialize in the mounted. When you're accessing the data, you should use this like this.nextBtn, also try to change the name of the variables so that they're not the same as the name of the method (e.g. in here you have nextBtn as a function and nextBtn as a variable).

Related