I have a vue.js project and am using Vuex for my store. I am trying to process all notifications to users within the store and I am having some issues with async/await.
I am sure its something very simple and trivial but I am stuck. Any help is much appreciated.
Here is my function
async getNotifications() {
console.log('1')
const internalNotifications = await this.$store.getters['AppData/getInternalNotifications']
console.log('2')
if(internalNotifications) {
this.notifications = internalNotifications
this.message = true
console.log('4 ', internalNotifications)
}
}
Here is my function in the store to get the notifications and dispatch them.
async getInternalNotifications({ dispatch }, { cid, user, roles, isSupperAdmin }) {
console.log('getInternalNotifications')
let internalNotifications = []
// Get all the notifications for this church
let getAllNotifications = await db
.collection('notifications')
.where('cid', '==', cid)
.where('active', '==', true)
.orderBy('created')
.get()
for (const notificationDoc of getAllNotifications.docs) {
let notification = notificationDoc.data()
notification.id = notificationDoc.id
// check to make sure this notification has not already been read
let getAllReadNotifications = await db
.collection('notificationsread')
.where('notificationid', '==', notification.id)
.where('userid', '==', user.uid)
.get()
if (getAllReadNotifications.empty)
internalNotifications.push(notification)
}
if (!isSupperAdmin && internalNotifications.length > 0) {
const hasAudience = internalNotifications.filter((el) => {
return roles.some(r => el.audience.includes(r))
})
hasAudience.sort((a, b) => (a.created < b.created) ? 1 : -1)
internalNotifications = hasAudience[0]
}
console.log('3 ', internalNotifications)
dispatch('addInternalNotification', internalNotifications)
},
My thinking is when viewing the console log I should see the logs in order 1,3,2,4 but instead I get 1,2,4,3 and as you can see from the screen shot it's an Observer not the actual array/object.
see screen shot of console log
CodePudding user response:
I was working on a web app recently and I think I can help. Someone correct me if I'm wrong, but typically after calling an async function, I follow it with a .then
. Example:
const myPromise = anAsyncFunction() // should return a promise
myPromise.then (
function(value) {
// function to be executed when the async function is finished
},
function(error) {
// error handling
}
)
Otherwise, my app would not wait for the async function to finish and would not have the right variable in time to process it.
CodePudding user response:
What appears to be happening, and looking at the order of logs, is that this.$store.getters
does not return a Promise
and therefore adding await
does nothing.
Make sure that this.$store.getters
is actually returning a Promise that can be awaited or look at using Actions
. From the docs if you wanted to use an action for this, you could try something like the following:
NOTE All of this is untested and I don't know vue, so use with caution knowing changes may be needed and best practices may not be getting followed by this approach.
actions: {
async getInternalNotifications({ dispatch }) {
return new Promise((resolve, reject) => {
console.log('getInternalNotifications')
let internalNotifications = []
// Get all the notifications for this church
let getAllNotifications = await db
.collection('notifications')
.where('cid', '==', cid)
.where('active', '==', true)
.orderBy('created')
.get()
for (const notificationDoc of getAllNotifications.docs) {
let notification = notificationDoc.data()
notification.id = notificationDoc.id
// check to make sure this notification has not already been read
let getAllReadNotifications = await db
.collection('notificationsread')
.where('notificationid', '==', notification.id)
.where('userid', '==', user.uid)
.get()
if (getAllReadNotifications.empty)
internalNotifications.push(notification)
}
if (!isSupperAdmin && internalNotifications.length > 0) {
const hasAudience = internalNotifications.filter((el) => {
return roles.some(r => el.audience.includes(r))
})
hasAudience.sort((a, b) => (a.created < b.created) ? 1 : -1)
internalNotifications = hasAudience[0]
}
console.log('3 ', internalNotifications)
dispatch('addInternalNotification', internalNotifications)
resolve(internalNotifications)
// TODO: Reject error scenarios, e.g. wrap you db calls in a try...catch and reject the promise with the error
})
}
async getNotifications() {
console.log('1')
const internalNotifications = await this.$store.dispatch('AppData/getInternalNotifications')
console.log('2')
if(internalNotifications) {
this.notifications = internalNotifications
this.message = true
console.log('4 ', internalNotifications)
}
}