In my VueJS application I make an API call to get user statistics that I want to present to the user. It is rather simple with Java backend and an $axios
get request. When I just run the app the first time and view the page, it is all working as expected, but when updating the page or going to some other page and going back, the values are instead 0.
I guess it is because the DOM for whatever reason is not updated, but if I open the development tools and look in the "Network" section, I can see that the API call is being made and that I do get the data, it is just not displayed
<template>
<div>
<h3>Users:</h3>
<v-container >
<v-row
v-for="(d, index) in data"
:key="index"
no-gutters
>
<v-col>
<v-card
outlined
tile
>
{{ d.title }}
</v-card>
</v-col>
<v-col>
<v-card
outlined
tile>
{{ d.value }}
</v-card>
</v-col>
</v-row>
</v-container>
</div>
</template>
<script>
import {Component, Vue} from "vue-property-decorator";
@Component({
created() {
this.$accessor.users.loadNumOfNewUsers()
},
mounted() {
this.newUsers()
}
})
export default class ShowNewUsers extends Vue {
data = [
{ title: "New users:", value: -1 },
]
newUsers() {
Vue.set(this.data[0], "value", this.$accessor.users.newUsers);
}
}
</script>
The API calls (like this.$accessor.users.loadNumOfNewUsers()
and this.$accessor.users.newUsers
) are made from an API call to my Java backend, in this case it looks like this, and as I stated seems to work just fine
import {actionTree, getterTree, mutationTree} from "typed-vuex";
export const state = () => ({
newUsers: 0,
});
export type AdminState = ReturnType<typeof state>;
export const getters = getterTree(state, {
newUsers: (state: AdminState) => state.newUsers,
});
export const mutations = mutationTree(state, {
setNumOfNewUsers(state: AdminState, numOfNewUsers) {
state.newUsers = newUsers
}
});
export const actions = actionTree(
{state, getters, mutations},
{
async loadNumOfNewUsers({commit}) {
const numOfNewUsersUrl = '/api/my/java/backend'
await this.$axios.get(numOfNewUsersUrl).then((response) => {
commit('setNumOfNewUsers', response.data)
})
},
},
);
Is it that I have to use the @Watch
decorator maybe? But the way I understand it is that is only needed if I want changes to be responsive, it should still work to just reload the page. Also it is strange that I get 0 as the value instead of -1 (which is its base value). This probably mean that there is some yanky JavaScript converson from NaN perhaps, but honestly have no ideea.
CodePudding user response:
A solution to this that however do not include TypeScript is to create computed
and watch
modules where computed
look at when fetching the value and also update it when it changes and then actually updating items
data variable with the watch
module waiting for this to happen and then updating the variable to present.
<template>
<v-data-table
:headers="headers"
:items="items"
:items-per-page="5"
></v-data-table>
</template>
<script>
export default {
name: "NewUsers",
data: () => ({
headers: [
{text: 'What', value: 'what'},
{text: 'Number', value: 'num'}
],
items: []
}),
computed: {
getNewUsers() {
return this.$accessor.admin.newUsers
}
},
watch: {
getData() {
this.items.push({what: 'Number of new users', num: this.getNewUsers})
}
},
mounted() {
this.$accessor.admin.loadNumOfNewUsers()
},
}
</script>