Uncoke
Uncoke

Reputation: 1902

Vue.js destroy a setInterval running inside a component

In my SPA made with VUE I have a component running a recursive few of setInterval functions (it's a countdown). I noticed the countdown continue in the background when I switch view to another component, but I prefer to destroy the setInterval.

I tried using a global data having the countdowns and then destroy it on destroyed hook but it doesn't work.

Here my code:

    data: function () {
        return {
            counters: ""
        }
    }),

   methods: {
     countdown(index, exp) {
        ...
          this.counters = setInterva()
        ...
        },
   },

   destroyed(){
        console.log(this.counters); // returns a progressive integer
        clearInterval(this.counters);
        console.log(this.counters); // returns same integer
        this.counters = 0;
        console.log("destroyed");
    } 

But in the console I got:

destroyed

app.js:64433 0

app.js:64398 Missing counter_1 . <--- which means counter is still running

Thanks for any suggestion!

Upvotes: 7

Views: 19252

Answers (5)

Hendry
Hendry

Reputation: 900

You should use beforeDestroy hook instead of destroyed

For reference on vue lifecycle check out https://v2.vuejs.org/v2/guide/instance.html#Lifecycle-Diagram

Upvotes: 1

Zagrios
Zagrios

Reputation: 71

In vue3 destroy() and beforeDestroy() has been deprecated.

Use unmount() or beforeUnmount() instead.

beforeUnmount(){
    clearInterval(this.counters);
}

Upvotes: 6

Anandhu Krishnan
Anandhu Krishnan

Reputation: 11

Use beforeRouteLeave route navigation guard inside route components to destroy setInterval. Add clearInterval function inside beforeRouteLeave, this will destroy the timer set by setInterval before we leave the component

beforeRouteLeave (to, from, next) {
    clearInterval(this.counters);
    next()
},

Upvotes: 0

T.Woody
T.Woody

Reputation: 1228

There might be two things happening here depending on if you are calling countdown or not:

1. countdown is not called

countdown(index, exp) needs to be defined in the created hook such as below. Furthermore, a method foo() should be bound to this interval for the expected functionality.

  created: function(){
      this.counterInterval =  setInterval(
        function()
        {
          this.foo();
        }.bind(this), 500);
    return this.foo();
  },
  destoyed: function(){
    clearInterval( this.counterInterval )
  },

2. countdown is called properly but the component is actually not getting destroyed

If the error is actually a misunderstanding on what it means to "destroy" the component, such that the component is not getting destroyed, the same code as above can be used, but a data prop of isShowing: true bounded within the JSX will solve the problems.

Just do a v-if check on isShowing and then do an event listener if the element is in view. If the element is in view, then we have isShowing===true. else, false.

Upvotes: 4

saleh shokouhi
saleh shokouhi

Reputation: 535

Try this Change destroyed() method to beforeDestroy().

update

maybe vue component did not destroy. try destroy manually

sorry for my bad English

Upvotes: 0

Related Questions