Vue.js polling using setInterval()

in Code Write a comment

I came up with an easy way to repeat a function in Vue.js. For instance, you want to periodically retrieve data from your database using the backend API/axios, without any additional packages.

Javascript

To achieve that you need to use the javascript method called setInterval(). It’s a simple function that would repeat the same task over and over again. Here’s an example:

function myFunction() {
	setInterval(function(){ alert("Hello world"); }, 3000);
}

If you add a call to this method for any button and click on it, it will print Hello world every 3 seconds (3000 milliseconds) until you close the page.

First attempt using Vue.js

created () {
	setInterval(() => {
		this.$store.dispatch('RETRIEVE_DATA_FROM_BACKEND')
	}, 3000)
}

This is a good approach but the problem is — it will keep running after you switch to another page, because it’s a single page application.

Second attempt using Vue.js

You need to call clearInterval() method to clear the timer set in setInterval() method.

To do so you need to pass the ID value returned by setInterval() to the clearInterval() method.

Here is an example:

data () {
	return {
		polling: null
	}
},
methods: {
	pollData () {
		this.polling = setInterval(() => {
			this.$store.dispatch('RETRIEVE_DATA_FROM_BACKEND')
		}, 3000)
	}
},
created () {
	this.pollData()
}

Note how we assigned our setInterval() method to the polling object. We’re now going to pass it to the clearInterval() method.

To do that we use a function called beforeDestroy(). It’s called right before a Vue instance is destroyed. At this stage, the instance is still fully functional.

It will prevent memory leaks that setInterval() method can cause.

beforeDestroy () {
	clearInterval(this.polling)
}

Hi, I'm Renat 👋

 


This is it, we’ve just cleared the timer method and stopped polling data from the backend.

Full example

data () {
	return {
		polling: null
	}
},
methods: {
	pollData () {
		this.polling = setInterval(() => {
			this.$store.dispatch('RETRIEVE_DATA_FROM_BACKEND')
		}, 3000)
	}
},
beforeDestroy () {
	clearInterval(this.polling)
},
created () {
	this.pollData()
}

If you find this post useful, please let me know in the comments below. 
Cheers,
Renat Galyamov

Want to share this with your friends?
👉renatello.com/vue-js-polling-using-setinterval

PS: Make sure you check other Vue.js tutorials, know the difference between LocalStorage vs SessionStorage vs Cookies, know how to check if a user has scrolled to the bottom in Vue.js and learn how to print Javascript object in console, Vue.js hosting.

A collection of UI components for
Bootstrap 4/5 and Vue.js

Get now

Write a Comment

Comment

49 Comments

  1. Thanks, this was just the resource I was looking for! Thank you for fleshing out the example to prevent memory leaks and build a habit of using the lifecycle hooks to best use!

  2. I needed something exactly as the first attempt and as I’m a beginner at JS and Vue, I was complicating things so much. I spent like 3 ~ 4 hours trying to do what I was trying to do, but it got buggy, hard to read and understand and it was not exatcly what I wanted.
    If I’d searched a little more, I woudn’t in pain like now LOL. Anyway, thank you, you saved me.

  3. Hi Renat, thank you for the article!! Very Helpfull!! Just wondering if you have any suggestions, I have this action running on a header element for notifications and need to then clear the poll action once a user logs out?

    • Hi Johno! You’re very welcome!
      You can create a method that will clear the poll action and call it from another component using refs (https://renatello.com/vue-js-refs/) or create a new custom watcher (inside the Notifications.vue component) that will clear the poll action once the user state changes in the computed() property.

  4. By the way… what about this in order to:
    1. Fill charts with data on page load
    2. Refresh data every 5 seconds
    ____

    methods: {
    getChartsData() {
    axios
    .get(‘server/chartsCollection.json’)
    .then(response => (this.chartsData = response.data))
    .catch(error => console.log(error))
    },
    updateData() {
    this.polling = setInterval(() => {
    this.getChartsData();
    }, 5000)
    }
    }

    • How can we load the data without delay the first time and then use and interval but with fetch API and not with axios ?
      updateData() does not work with fetch API

      • Hi Anastasios, you can fetch data without delay by placing your call in the created() function. E.g.

        created() {
        this.getData() // create a method that fetches/stores data in the data() object
        this.pollData() // and then use the interval method that will keep fetching data from the backend
        }

    • That’s a good point, Marcelo. I guess it can cause memory loss in some rare cases e.g. it will depend on a browser, polling interval and device memory.

      I’ve just tested this example https://jsfiddle.net/renatello/u5nyfq4r/ in Chrome on my 16gb laptop. It created tens of thousands GET requests without creating any spikes in memory usage.

      It’s interesting to see how it works on your device(s). Let me know!

  5. Hi,
    Thank you for this post very useful.
    I would like to stop the API calls when the browser displays another website in another tab (or on mobile context, when the app is not active).
    Is there a way do to that ?

  6. I was close, but this pushed me over the edge and was just what i was looking for. Thank you!!!

  7. Hi there, I’ve tried this in an nuxt SSR application. When I leave the webpage Before destroy does not stop the polling task. It keeps running. Can you tell me how I can kill the pollling task when user leaves page?

    • Hi Tom! Try to debug it by adding a console.log('Leave page') to the beforeDestroy() function and see if it works at all.

  8. Awesome. Just what I wanted to kickstart my project. I’m porting my project from django to vue, and was looking for exactly this. So simple yet elegant.

      • Hello there
        thanks for your work. but I pull data from the server with axios every 3 seconds. But after a while, the page crashes with the error “ERR_INSUFFICIENT_RESOURCES”. How can I find a solution to this? thanks

  9. I Have a problem similar to that, but im my case I need to watch if a variable has changed due to an update from the server (inside the created).
    In the watch, inside a condition, I triggered a setInterval (to emit a sound periodically) and in the else I call the clearInterval(this.variable), but the interval doesn`t stops and when a console.log(this.variable) it`s not empty