Optimal method to refresh v-for when updating route in Vue.js seamlessly without having to manually reload the page

What is the best approach to re-render a v-for loop in my Vue.js application when switching to another route?

In my scenario, I am using Vuex, vuex-persistedstate, and moment for saving data in localStorage and displaying timestamps like "a moment ago".

However, how can I trigger a re-render of the v-for loop without changing the data from my API or manually reloading the page?

If you look at the screenshot below:

https://i.sstatic.net/kAmuV.png

The Recent Activity data is always cached in localStorage. But if there are no new updates from the API, how can I ensure that the timestamps continue to update (e.g., "3 minutes ago", "4 minutes ago") without having to refresh the page manually?

This currently only happens upon page reload because of my code structure:

<template>
<div class="widget">
    <h4 class="widget-title">Recent Activity</h4>
    <ul class="activitiez">
        <li v-for="act in recentActivity" :key="act._id" :id="act._id">
            <div class="activity-meta">
                <i v-html="convertToMoment(act.created_at)"></i>
                <span v-html="act.activity"></span>
                <h6>by <a href="#" v-html="act.sent_name"></a></h6>
            </div>
        </li>
    </ul>
</div>
</template>

<script>
import {mapGetters, mapActions} from "vuex"

export default {
    created() {
        this.fetchRecentActivityData()
    },
    computed: {
        ...mapGetters(["recentActivity"])
    },
    methods: {
        ...mapActions(["fetchRecentActivityData"]),
        convertToMoment(data) {
            return moment(data).fromNow()
        }
    },
}
</script>

<style>

</style>

And here is my Vuex store code:

import axios from 'axios';

const state = {
    recentActivityStore: [],
    errorBag: null,
    timingStore: Date.now()
};

const getters = {
    recentActivity: state => state.recentActivityStore,
    recentActivityTiming: state => state.timingStore
};

const actions = {
    async fetchRecentActivityData({ commit }) {
        const recentAct = this.state.recentactivity.recentActivityStore
        if(_.isEmpty(recentAct)) {
            const response = await axios.get('/recent/activity')
            commit('UPDATE_RECENT_ACTIVITY', response.data)
        }
        commit('UPDATE_TIMING', Date.now())
    }
};

const mutations = {
    UPDATE_RECENT_ACTIVITY: (state, data) => {
        state.recentActivityStore = data
    },
    UPDATE_TIMING: (state, data) => {
        state.timingStore = data
    }
};

export default {
    state,
    getters,
    actions,
    mutations
};

How can I achieve auto-refreshing of my v-for loop without manual page refresh so that the timestamps keep updating? Any help would be greatly appreciated.

Thank you!

Answer №1

Here is a link to the Codepen example: https://codepen.io/anon/pen/qvgxRJ

To tackle this issue, you can create a Vue filter. Here's the code snippet for the filter: Vuejs time ago filter


filters: {
  timeago: function (pdate, ctime) {
     if (!pdate || !ctime) return ''
     return moment(pdate).from(ctime)
   }
 },
 

Once you have created the filter, you need to apply it in your HTML like this:

<i>{{act.created_at | timeago(currenttime)}}</i>

This calculates the time ago based on the current time. To keep updating the component every 50 seconds, update the current time value in setInterval:


data:()=>({
 currenttime: Date.now(),
 timer: ''
 }),
created() {
    this.fetchRecentActivityData()
    this.timer = setInterval(() => {this.currenttime = Date.now()}, 50000);
}

Here is the final code snippet that incorporates all these functionalities:


export default {
 data:()=>({
 currenttime: Date.now(),
 timer: ''
 }),
 filters: {
  timeago: function (pdate, ctime) {
     if (!pdate || !ctime) return ''
     return moment(pdate).from(ctime)
   }
 },
 created() {
    this.fetchRecentActivityData()
    this.timer = setInterval(() => {this.currenttime = Date.now()}, 50000);
 },
 beforeDestroy() {
    clearInterval(this.timer)
 },
 computed: {
    ...mapGetters(["recentActivity"])
 },
 methods: {
    ...mapActions(["fetchRecentActivityData"]),
 },
}

And in your HTML template, you can use the filter like this:


<li v-for="act in recentActivity" :key="act._id" :id="act._id">
    <div class="activity-meta">
        <i>{{act.created_at | timeago(currenttime)}}</i>
        <span v-html="act.activity"></span>
        <h6>by <a href="#" v-html="act.sent_name"></a></h6>
    </div>
</li>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

encountering a problem with retrieving the result of a DOM display

private scores = [] private highestScore: number private studentStanding private studentInformation: any[] = [ { "name": "rajiv", "marks": { "Maths": 18, "English": 21, "Science": 45 }, "rollNumber": "KV2017-5A2" }, { "n ...

Exploring the power of combining observables in RxJS

Having difficulty combining observables in my implementation of a tags-input feature. this._allTags represent all available tags. I am working with 4 streams: this._suggestions = new this.rx.Subject; this._searchText = new this.rx.Subject; this._s ...

Sending Grunt Jade configurations to a specific file

I'm currently using grunt-contrib-jade and I'm trying to utilize the pkg.name and pkg.version variables to generate my css file name. Unfortunately, I haven't been able to make this work on my own and would appreciate any assistance. Below i ...

How to work with a JSON object in Internet Explorer 6

Looking for some quick answers that should be easy for someone with expertise to provide. I have a basic asp.net site that relies on JSON for various tasks (and JSON.stringify). Everything works fine in Firefox and the like, but in IE6 I'm getting a ...

export default select an option

Forgive me if my question comes off as naive, but I'm still learning the ropes. :-) I stumbled upon something perplexing in this GitHub file. I am aware that we can export or import default functions, but in this instance, the author has used: expo ...

Vue.js 2 maintains a collection of items

I have a method that renders a list, but when I click on one of the list items, the list disappears. I also added the showDetail() method. How can I prevent the list from disappearing? data: function () { return { show ...

Mastering Backbone views and router functionality is essential for building scalable and efficient web

In my code, I have a series of page states that mimic the steps of a shopping cart checkout process. The first set of code sets up the ItemsCollection, ItemsView, and ItemsApp in Backbone.js. var ItemsCollection = Backbone.Collection.extend({ model: I ...

What strategies can I use to eliminate nested loops while constructing a navigation?

I am working with a JSON file that contains data for a navigation panel consisting of links. A brief snippet of the file is shown below: [ { "category": "Pages", "links": [ { "url": "#", "cap ...

The bespoke node package does not have an available export titled

No matter what I do, nothing seems to be effective. I have successfully developed and launched the following module: Index.ts : import ContentIOService from "./IOServices/ContentIOService"; export = { ContentIOService: ContentIOService, } ...

$routeProvider - providing controller dependencies based on the URL path

Take a look at the following code snippet: var app = angular.module("app", [], function($routeProvider) { $routeProvider .when("/page1", { controller: "MyController" }) .when("/page2", { controller: "MyController" }) .when("/page3", { contro ...

Refresh the Dom following an Ajax request (issue with .on input not functioning)

I have multiple text inputs that are generated dynamically via a MySQL query. On the bottom of my page, I have some Javascript code that needed to be triggered using window.load instead of document.ready because the latter was not functioning properly. & ...

What is the jquery alternative to the PHP 'if IP equals' condition?

I am curious to know if the following PHP 'if' conditions can be achieved in jquery or JavaScript, with a preference for jquery. if ($_SERVER['REMOTE_ADDR'] != '123.99.55.616') { // public doingness } if ($ ...

Using Ajax to update a MySQL database with an array from jQuery

I need some assistance in updating a MySQL table using data from a jQuery array through AJAX. I've tried searching for similar issues without any luck, possibly due to my lack of familiarity with the correct terms in web development and coding. Allow ...

Synchronize information between two drop-down lists

I am currently utilizing the boostrap library to create a pair of dropdown lists. My goal is to have the items in the second dropdown list dynamically update based on the selection made in the first dropdown. Within my code, there exists a dictionary name ...

Save pictures in MongoDB using GridFS or BSON format

As a newcomer to MongoDB, I am seeking advice on the best way to store images in the database. Gridfs and BSON seem to be the most common options, but I'm unsure about their respective pros and cons. The main difference I'm aware of is the 16MB s ...

What's the reason "console.log()" doesn't function on this particular site?

When I go to https://www.google.com/ and enter console.log("Hello world!") into the Chrome DevTools console, it prints "Hello world!" as expected. However, when I try the same command on , nothing shows up in the console. Why doesn't it work for this ...

Safari's Web Audio API suffering from subpar performance and various shortcomings

For my University project, I am developing an HTML and JavaScript-based mp3 player using the Web Audio API. You can check out the progress of this project by visiting this link: While everything is running smoothly on Firefox and Chrome, Safari is posing ...

What are the steps to fix a timeout error with React.js and socket.io acknowledgements?

My setup includes a Node.js server and a React.js client application. Data is exchanged between them using socket.io, but I'm running into an issue with implementing acknowledgment. Whenever I try to implement acknowledgment, I receive a timeout error ...

Is there a specific method to access a JSON file with (js/node.js)?

Searching for a way to access user information stored in a JSON file using the fs module in node.js. Specifically looking to read only one user at a time. app.get("/1", function(req, res) { fs.readFile("users.json",function(data, err){res.write(data)}} W ...

Implementing the @media rule using Javascript

I'm trying to use JavaScript to add an image dynamically, but I want to remove it when the viewport is 600px or wider. This is my approach so far: var img = document.createElement('img'); // (imagine here all the other fields being defined ...