1đź‘Ť
You are executing several asynchronous Firebase operations in your deleteProject
method (calling Firestore get()
, Firestore delete()
, Cloud Storage delete()
, …) but you are not correctly chaining the different Promises returned by these Firebase methods.
You have to chain those Promises with the then()
method , which “returns a Promise which allows for method chaining”.
So, the following should do the trick (untested however):
export const deleteProject = {
methods: {
deleteProject (yearId, projectId) {
// delete project, all documents in the images subcollection of the project, and all stored images
return firebase.firestore().collection('years').doc(yearId).collection('projects').doc(projectId).get()
.then((doc) => {
// delete thumbnail
return firebase.storage().ref(doc.data().thumbFullPath).delete()
})
.then(() => {
return firebase.firestore().collection('years').doc(yearId).collection('projects').doc(projectId).delete();
})
.then(() => {
return firebase.firestore().collection('years').doc(yearId).collection('projects').doc(projectId).collection('images').get()
})
.then((querySnapshot) => {
const promises = [];
querySnapshot.forEach((doc) => {
// delete gallery image
this.imagePaths.append(doc.data().fullPath)
// delete reference document for gallery image
promises.push(doc.ref.delete());
})
return Promise.all(promises);
})
}
}
}
And since this deleteProject()
method is now asynchronous, you need to call it as follows in your mixin:
methods: {
del () {
// call deleteYear method from mixin
this.deleteProject(this.yearId, this.projectId)
.then(() => {
// emit reload signal for database relaod
this.$emit('reload')
// close modal
this.dialog = false
})
}
}
Note that we use Promise.all()
to execute in parallel all the delete()
method calls in the forEach()
. Promise.all()
method returns a single Promise that fulfills when all of the promises passed to as an iterable (i.e. the promises
array) have been fulfilled.
2đź‘Ť
You simply need to return the foremost .then()
in the Promise chain of this deleteProject
method, and any subsequent call should be able to pick it up from this point.
deleteProject() {
// Add a return keyword here, or assign the Promise to a variable and return it.
return firebase.firestore().collection('years').doc(yearId).collection('projects').doc(projectId).get()
.then( /* removed for brevity */ )
}
The calling method,
methods: {
del() {
this.deleteProject(this.yearId, this.projectId).then(() => {
this.$emit('reload')
})
}
}
Or, make it “prettier” with the async
keyword,
methods: {
async del() {
// You probably want to do try-catch here as well.
await this.deleteProject(this.yearId, this.projectId);
this.$emit('reload');
}
}