Search code examples
vue.jssettimeoutcleartimeout

vue.js, setTimeout interfere with my simple countdown


i have simplified my code to clarify the problem, this vue page shows a question for ten seconds and the student should say the answer before it shows up, but here is the problem, i have a next button which shows the next question, consider 5 seconds left and you press the next button then countdown completely tears apart, even it shows minus digits!

<template>
  <div class="container text-center">
      <div v-if = "showQuestion">
     <span> {{ question }} </span>
      <span style="color:red;"> &nbsp;&nbsp;&nbsp;{{ countDown }} </span>

    </div>

    <div v-if = "showAnswer">
            <p> {{ answer }} </p>
    </div>

    <div>
       <button class="btn btn-success" @click="next">next question </button>
         
    </div>
     
  </div>
</template>

<script>
export default {
     data(){
        return{
            questions: ['question1', 'question2', 'question3', 'question4', 'question5'] ,   
            answers: ['answer1', 'answer2', 'answer3', 'answer4', 'answer5'],
           
            question: '',
            answer: '',
           mayVar: null, //controlls setTimeout
            index : 0, 
             showQuestion: true,
             showAnswer: false,
              countDown : 10,           
            
        }
    },
    methods:{
        
            startQuiz(){
               this.countDown = 10;
               this.question = this.questions[this.index];
               this.answer = this.answers[this.index];
               this.countDownTimer();
               this.show();
              
            },

            show(){                
                 this.myVar =  setTimeout(() => { //question fades away and answer shows up
                       this.showQuestion = false;
                       this.showAnswer = true;

                    }, 10000);
            },

             next(){
                  clearTimeout(this.myVar); // 
                 this.index++;// goes to next question
                   this.showQuestion = true;
                 this.showAnswer = false;
                this.startQuiz();
                
             },
                 
             countDownTimer() {
                  
                if(this.countDown > 0) {
                    setTimeout(() => {
                        this.countDown--;
                        this.countDownTimer();
                    }, 1000);
                }
            },
    },

    created(){
      this.startQuiz();
    }
}
</script>

<style>

</style>

thank you

here is the link for jsfiddle


Solution

  • You should clear the countdown timer also, when you press next. See the below snippet.

    const app = new Vue({
    el: "#app",
    data(){
            return{
                questions: ['question1', 'question2', 'question3', 'question4', 'question5'] ,   
                answers: ['answer1', 'answer2', 'answer3', 'answer4', 'answer5'],
               
                question: '',
                answer: '',
               mayVar: null, //controlls setTimeout
                index : 0, 
                 showQuestion: true,
                 showAnswer: false,
                  countDown : 10,   
                  count_down_timer: null // controls count down timer
                
            }
        },
        methods:{
            
                startQuiz(){
                   this.countDown = 10;
                   this.question = this.questions[this.index];
                   this.answer = this.answers[this.index];
                   this.countDownTimer();
                   this.show();
                  
                },
    
                show(){                
                     this.myVar =  setTimeout(() => { //question fades away and answer shows up
                           this.showQuestion = false;
                           this.showAnswer = true;
    
                        }, 10000);
                },
    
                 next(){
                      clearTimeout(this.myVar); // 
                      clearTimeout(this.count_down_timer)
                     this.index++;// goes to next question
                       this.showQuestion = true;
                     this.showAnswer = false;
                    this.startQuiz();
                    
                 },
                     
                 countDownTimer() {
                      
                    if(this.countDown > 0) {
                        this.count_down_timer = setTimeout(() => {
                            this.countDown--;
                            this.countDownTimer();
                        }, 1000);
                    }
                },
        },
    
        created(){
          this.startQuiz();
        }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
    <div class="container text-center">
          <div v-if = "showQuestion">
         <span> {{ question }} </span>
          <span style="color:red;"> &nbsp;&nbsp;&nbsp;{{ countDown }} </span>
    
        </div>
    
        <div v-if = "showAnswer">
                <p> {{ answer }} </p>
        </div>
    
        <div>
           <button class="btn btn-success" @click="next">next question </button>
             
        </div>
         
      </div>
    </div>