i have a question regarding Javascript Promises in a VueJS setting, i have an application that uses an Action to either fetch a list of Countries from IndexedDB (if it's set ) or from an API by making an Axios HTTP Request.
Now, i'm returning a promise from the action because i want to be able to trigger some popups in the UI when this task is completed, and on top of that both Axios and Dexie(which im using for IndexedDB) run asyncronously through Promises themselves.
getCountries({commit, dispatch}) {
commit(types.MUTATIONS.SET_LOADING, true, {root: true})
commit(types.MUTATIONS.SET_LOADER_MESSAGE, "Loading Countries Data...", {root: true})
return new Promise((resolve, reject) => {
db.countries.count().then(value => {
if(value > 0) {
console.log("Loading Countries from IndexedDB")
db.countries.toArray().then(collection => {
commit(types.MUTATIONS.COUNTRIES.SET, collection, {root: true})
resolve(collection);
})
} else {
fetchCountriesData().then(data => {
console.log("Loading Countries from API Call")
commit(types.MUTATIONS.COUNTRIES.SET, data, {root: true})
db.countries.bulkAdd(data)
resolve(data)
}).catch(error => {
reject(error)
})
}
})
})
}
That is the code for the action, it simply does what i described above, the problem is that this results in an infinite loop where the LOADER Mutations get triggered over and over again.
Why exactly is this going on? Can anyone help me make sense of this? It seems that it runs the initial API action, but THEN after that, with the countries already loaded, it loops and runs again this time invoking the indexeddb mutation as well, which is strange, if i resolve it shouldn't it just end there?
EXTRA::
The action is invoked in a view that i have in my application, i invoke this in the created()
hook so that i make sure that the list of countries is always loaded in my Vuex State.
created() {
this.getAllCountries().then(response => {}).catch(error => {
snackbar("Unable to load countries!", "error")
}).then(() => {
this.setLoadingStatus(false);
})
}
In this context, it does nothing if it's ok, but that might change in the future, on errors it should show a popup informing the users that the data could not be loaded, and in either case it should hide the loading bar (which is also handled through Vuex)
Could this be the cause of the problem?