I'm trying to display a list of announcements (retrieved from API) on the page. I'm using Vuex store and I have a state called announcements. I also want this list to be updated every time the user refreshes/enters the page. So I used lifecycle hooks, particularly the mounted(). I have a dispatch function that takes a club ID as a parameter. The issue is that I try to access the announcement array in the Vue component, it is one "step" behind the version in the Vuex store.
The Following is in the Vue component ClubDetails.vue
name: "ClubDetails",
data(){
console.log("inside data")
return {
club_id: this.$route.params.clubID,
announcements: this.$store.state.ClubDetails.announcements
}
},
mounted() {
this.$store.dispatch('ClubDetails/getAnnouncements', this.club_id)
console.log("After dispatch function")
},
This is my store ClubDetails.js
namespaced: true,
state: {
announcements: [],
},
mutations: {
setAnnouncements(state, newArr) {
state.announcements = newArr
console.log("Inside Mutation")
},
},
actions: {
async getAnnouncements({ commit, state }, club) {
const params = new URLSearchParams([
['clubId', club]
]);
await axios.get("http://127.0.0.1:8000/api/announcements", { params }).then(res => {
console.log("inside dispatch function")
commit('setAnnouncements', res.data)
}).catch(err => {
console.log(err)
})
},
},
getters: {
getAllAnnouncements(state) {
return state.announcements;
}
},
};
After the print statements, the order of execution is not what i expected
I expected the order to be like this: inside data -> inside dispatch -> inside mutation -> after dispatch.
Another issue is that when I refresh the page, i expected mounted() to be called again and the array would be updated and displayed again, but when refreshing all the contents of the array disappear
CodePudding user response:
This is because this.$store.dispatch('ClubDetails/getAnnouncements', this.club_id)
is making a response to a server and is asynchronus and takes time for the announcemnts to be fetched from the server. While console.log("After dispatch function")
gets executed before a response is recieved from the server.
Thats why you see After dispatch function first and inside dispatch function later.
Try putting await before the dispatch like this.
async mounted() {
await this.$store.dispatch('ClubDetails/getAnnouncements', this.club_id)
console.log("After dispatch function")
},
You should return the axios.get method as it is a Promise and no need to use await and then together. You can also remove the async from getAnnouncements
as you are no longer using await.
getAnnouncements({ commit, state }, club) {
const params = new URLSearchParams([
['clubId', club]
]);
return axios.get("http://127.0.0.1:8000/api/announcements", { params }).then(res => {
console.log("inside dispatch function")
commit('setAnnouncements', res.data)
}).catch(err => {
console.log(err)
})
},