How to wait for Promise to resolve before returning a new Promise?












3















I'm building a web application for creating retail signage. Firestore holds information about the signs, and I want to be able to remove all of the signs if a user clicks on 'Remove all Signs.' A dialog will then appear which will ask the user to confirm deleting all signs in the database. If they confirm, then all the signs should then be deleted from Firestore.



The document ID of each sign is stored in an array called signIds. I want to be able to iterate through signIds and delete each document from the signs collection in Firestore. Once all the Promises have resolved, I want to return a Promise and resolve it in the event handler in mounted().



I've tried returning a Promise at different places in the code, to no avail. I've also tried using async and await but that seemed to have the same issue.



data() {
return {
signIds: ,
}
},
methods: {
showModal(message, type) {
this.$root.$emit('openModal', {
closed: false,
text: message,
type: type
})
},
emptyQueue() {
let self = this;
let deleted = 0;

for (let id of self.signIds) {
database.collection("signs").doc(id).delete()
.then(() => {
console.log("Document successfully deleted!");
deleted++;
}).catch((error) => {
console.error("Error removing document: ", error);
});
}

// Once all signs are deleted, return new Promise
return new Promise((resolve, reject) => {
return (deleted === self.signIds.length) ? resolve() : reject(new Error('An error occurred while deleting signs.'));
});
}
},
created() {
// Get and store the document id for each sign
database.collection("signs").get()
.then(snapshot => {
snapshot.forEach(doc => {
this.signIds.push(doc.id);
})
});
},
mounted() {
// When the user clicks 'OK' on the dialog, delete all signs from the database
this.emptyQueue()
.then(() => {
setTimeout(function() {
self.showModal('All signs were successfully removed.', 'success');
}, 300);
}).catch(() => {
setTimeout(function() {
self.showModal('An error has occurred. Some signs were not removed.', 'error');
}, 300);
})
}


I expect the new Promise to return after Firestore's Promises have resolved, but currently the new Promise is returned immediately after the for loop is finished.










share|improve this question



























    3















    I'm building a web application for creating retail signage. Firestore holds information about the signs, and I want to be able to remove all of the signs if a user clicks on 'Remove all Signs.' A dialog will then appear which will ask the user to confirm deleting all signs in the database. If they confirm, then all the signs should then be deleted from Firestore.



    The document ID of each sign is stored in an array called signIds. I want to be able to iterate through signIds and delete each document from the signs collection in Firestore. Once all the Promises have resolved, I want to return a Promise and resolve it in the event handler in mounted().



    I've tried returning a Promise at different places in the code, to no avail. I've also tried using async and await but that seemed to have the same issue.



    data() {
    return {
    signIds: ,
    }
    },
    methods: {
    showModal(message, type) {
    this.$root.$emit('openModal', {
    closed: false,
    text: message,
    type: type
    })
    },
    emptyQueue() {
    let self = this;
    let deleted = 0;

    for (let id of self.signIds) {
    database.collection("signs").doc(id).delete()
    .then(() => {
    console.log("Document successfully deleted!");
    deleted++;
    }).catch((error) => {
    console.error("Error removing document: ", error);
    });
    }

    // Once all signs are deleted, return new Promise
    return new Promise((resolve, reject) => {
    return (deleted === self.signIds.length) ? resolve() : reject(new Error('An error occurred while deleting signs.'));
    });
    }
    },
    created() {
    // Get and store the document id for each sign
    database.collection("signs").get()
    .then(snapshot => {
    snapshot.forEach(doc => {
    this.signIds.push(doc.id);
    })
    });
    },
    mounted() {
    // When the user clicks 'OK' on the dialog, delete all signs from the database
    this.emptyQueue()
    .then(() => {
    setTimeout(function() {
    self.showModal('All signs were successfully removed.', 'success');
    }, 300);
    }).catch(() => {
    setTimeout(function() {
    self.showModal('An error has occurred. Some signs were not removed.', 'error');
    }, 300);
    })
    }


    I expect the new Promise to return after Firestore's Promises have resolved, but currently the new Promise is returned immediately after the for loop is finished.










    share|improve this question

























      3












      3








      3








      I'm building a web application for creating retail signage. Firestore holds information about the signs, and I want to be able to remove all of the signs if a user clicks on 'Remove all Signs.' A dialog will then appear which will ask the user to confirm deleting all signs in the database. If they confirm, then all the signs should then be deleted from Firestore.



      The document ID of each sign is stored in an array called signIds. I want to be able to iterate through signIds and delete each document from the signs collection in Firestore. Once all the Promises have resolved, I want to return a Promise and resolve it in the event handler in mounted().



      I've tried returning a Promise at different places in the code, to no avail. I've also tried using async and await but that seemed to have the same issue.



      data() {
      return {
      signIds: ,
      }
      },
      methods: {
      showModal(message, type) {
      this.$root.$emit('openModal', {
      closed: false,
      text: message,
      type: type
      })
      },
      emptyQueue() {
      let self = this;
      let deleted = 0;

      for (let id of self.signIds) {
      database.collection("signs").doc(id).delete()
      .then(() => {
      console.log("Document successfully deleted!");
      deleted++;
      }).catch((error) => {
      console.error("Error removing document: ", error);
      });
      }

      // Once all signs are deleted, return new Promise
      return new Promise((resolve, reject) => {
      return (deleted === self.signIds.length) ? resolve() : reject(new Error('An error occurred while deleting signs.'));
      });
      }
      },
      created() {
      // Get and store the document id for each sign
      database.collection("signs").get()
      .then(snapshot => {
      snapshot.forEach(doc => {
      this.signIds.push(doc.id);
      })
      });
      },
      mounted() {
      // When the user clicks 'OK' on the dialog, delete all signs from the database
      this.emptyQueue()
      .then(() => {
      setTimeout(function() {
      self.showModal('All signs were successfully removed.', 'success');
      }, 300);
      }).catch(() => {
      setTimeout(function() {
      self.showModal('An error has occurred. Some signs were not removed.', 'error');
      }, 300);
      })
      }


      I expect the new Promise to return after Firestore's Promises have resolved, but currently the new Promise is returned immediately after the for loop is finished.










      share|improve this question














      I'm building a web application for creating retail signage. Firestore holds information about the signs, and I want to be able to remove all of the signs if a user clicks on 'Remove all Signs.' A dialog will then appear which will ask the user to confirm deleting all signs in the database. If they confirm, then all the signs should then be deleted from Firestore.



      The document ID of each sign is stored in an array called signIds. I want to be able to iterate through signIds and delete each document from the signs collection in Firestore. Once all the Promises have resolved, I want to return a Promise and resolve it in the event handler in mounted().



      I've tried returning a Promise at different places in the code, to no avail. I've also tried using async and await but that seemed to have the same issue.



      data() {
      return {
      signIds: ,
      }
      },
      methods: {
      showModal(message, type) {
      this.$root.$emit('openModal', {
      closed: false,
      text: message,
      type: type
      })
      },
      emptyQueue() {
      let self = this;
      let deleted = 0;

      for (let id of self.signIds) {
      database.collection("signs").doc(id).delete()
      .then(() => {
      console.log("Document successfully deleted!");
      deleted++;
      }).catch((error) => {
      console.error("Error removing document: ", error);
      });
      }

      // Once all signs are deleted, return new Promise
      return new Promise((resolve, reject) => {
      return (deleted === self.signIds.length) ? resolve() : reject(new Error('An error occurred while deleting signs.'));
      });
      }
      },
      created() {
      // Get and store the document id for each sign
      database.collection("signs").get()
      .then(snapshot => {
      snapshot.forEach(doc => {
      this.signIds.push(doc.id);
      })
      });
      },
      mounted() {
      // When the user clicks 'OK' on the dialog, delete all signs from the database
      this.emptyQueue()
      .then(() => {
      setTimeout(function() {
      self.showModal('All signs were successfully removed.', 'success');
      }, 300);
      }).catch(() => {
      setTimeout(function() {
      self.showModal('An error has occurred. Some signs were not removed.', 'error');
      }, 300);
      })
      }


      I expect the new Promise to return after Firestore's Promises have resolved, but currently the new Promise is returned immediately after the for loop is finished.







      javascript firebase vue.js






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jan 1 at 23:47









      HeadAdmiralHeadAdmiral

      396




      396
























          3 Answers
          3






          active

          oldest

          votes


















          4














          Your current iteration through signIds's Promises is not being chained with anything else - the .delete() Promises aren't being used anywhere at the moment. It would be better to .map each id to a Promise in an array, then use Promise.all on that array. If errors are handled in the consumer, there's no need to catch in emptyQueue just to throw a new error - instead, just return the Promise chain alone, and avoid the explicit Promise construction anti-pattern:



          emptyQueue() {
          return Promise.all(
          this.signIds.map(id => (
          database.collection("signs").doc(id).delete()
          ))
          );
          }


          If any one of the .delete() calls result in an error, that error will percolate up to your



          this.emptyQueue()
          // ...
          .catch(() => {
          ...
          });


          section automatically via the Promise.all.






          share|improve this answer


























          • Great answer, it worked exactly as you wrote it with no errors at all!

            – HeadAdmiral
            Jan 2 at 1:02



















          1














          Making use of write batch may answer your needs https://firebase.google.com/docs/reference/js/firebase.firestore.WriteBatch






          share|improve this answer































            1














            You should be able to do that using batch, with a code that should look something like the following:



            // start a batch
            var batch = database.batch();

            for (let id of self.signIds) {
            // for each, add a delete operation to the batch
            batch.delete(database.collection("signs").doc(id));
            }

            // Commit the batch
            batch.commit();





            share|improve this answer























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53999827%2fhow-to-wait-for-promise-to-resolve-before-returning-a-new-promise%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              4














              Your current iteration through signIds's Promises is not being chained with anything else - the .delete() Promises aren't being used anywhere at the moment. It would be better to .map each id to a Promise in an array, then use Promise.all on that array. If errors are handled in the consumer, there's no need to catch in emptyQueue just to throw a new error - instead, just return the Promise chain alone, and avoid the explicit Promise construction anti-pattern:



              emptyQueue() {
              return Promise.all(
              this.signIds.map(id => (
              database.collection("signs").doc(id).delete()
              ))
              );
              }


              If any one of the .delete() calls result in an error, that error will percolate up to your



              this.emptyQueue()
              // ...
              .catch(() => {
              ...
              });


              section automatically via the Promise.all.






              share|improve this answer


























              • Great answer, it worked exactly as you wrote it with no errors at all!

                – HeadAdmiral
                Jan 2 at 1:02
















              4














              Your current iteration through signIds's Promises is not being chained with anything else - the .delete() Promises aren't being used anywhere at the moment. It would be better to .map each id to a Promise in an array, then use Promise.all on that array. If errors are handled in the consumer, there's no need to catch in emptyQueue just to throw a new error - instead, just return the Promise chain alone, and avoid the explicit Promise construction anti-pattern:



              emptyQueue() {
              return Promise.all(
              this.signIds.map(id => (
              database.collection("signs").doc(id).delete()
              ))
              );
              }


              If any one of the .delete() calls result in an error, that error will percolate up to your



              this.emptyQueue()
              // ...
              .catch(() => {
              ...
              });


              section automatically via the Promise.all.






              share|improve this answer


























              • Great answer, it worked exactly as you wrote it with no errors at all!

                – HeadAdmiral
                Jan 2 at 1:02














              4












              4








              4







              Your current iteration through signIds's Promises is not being chained with anything else - the .delete() Promises aren't being used anywhere at the moment. It would be better to .map each id to a Promise in an array, then use Promise.all on that array. If errors are handled in the consumer, there's no need to catch in emptyQueue just to throw a new error - instead, just return the Promise chain alone, and avoid the explicit Promise construction anti-pattern:



              emptyQueue() {
              return Promise.all(
              this.signIds.map(id => (
              database.collection("signs").doc(id).delete()
              ))
              );
              }


              If any one of the .delete() calls result in an error, that error will percolate up to your



              this.emptyQueue()
              // ...
              .catch(() => {
              ...
              });


              section automatically via the Promise.all.






              share|improve this answer















              Your current iteration through signIds's Promises is not being chained with anything else - the .delete() Promises aren't being used anywhere at the moment. It would be better to .map each id to a Promise in an array, then use Promise.all on that array. If errors are handled in the consumer, there's no need to catch in emptyQueue just to throw a new error - instead, just return the Promise chain alone, and avoid the explicit Promise construction anti-pattern:



              emptyQueue() {
              return Promise.all(
              this.signIds.map(id => (
              database.collection("signs").doc(id).delete()
              ))
              );
              }


              If any one of the .delete() calls result in an error, that error will percolate up to your



              this.emptyQueue()
              // ...
              .catch(() => {
              ...
              });


              section automatically via the Promise.all.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Jan 2 at 0:25

























              answered Jan 1 at 23:53









              CertainPerformanceCertainPerformance

              93.5k165484




              93.5k165484













              • Great answer, it worked exactly as you wrote it with no errors at all!

                – HeadAdmiral
                Jan 2 at 1:02



















              • Great answer, it worked exactly as you wrote it with no errors at all!

                – HeadAdmiral
                Jan 2 at 1:02

















              Great answer, it worked exactly as you wrote it with no errors at all!

              – HeadAdmiral
              Jan 2 at 1:02





              Great answer, it worked exactly as you wrote it with no errors at all!

              – HeadAdmiral
              Jan 2 at 1:02













              1














              Making use of write batch may answer your needs https://firebase.google.com/docs/reference/js/firebase.firestore.WriteBatch






              share|improve this answer




























                1














                Making use of write batch may answer your needs https://firebase.google.com/docs/reference/js/firebase.firestore.WriteBatch






                share|improve this answer


























                  1












                  1








                  1







                  Making use of write batch may answer your needs https://firebase.google.com/docs/reference/js/firebase.firestore.WriteBatch






                  share|improve this answer













                  Making use of write batch may answer your needs https://firebase.google.com/docs/reference/js/firebase.firestore.WriteBatch







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 1 at 23:58









                  Kevin CoulibalyKevin Coulibaly

                  1219




                  1219























                      1














                      You should be able to do that using batch, with a code that should look something like the following:



                      // start a batch
                      var batch = database.batch();

                      for (let id of self.signIds) {
                      // for each, add a delete operation to the batch
                      batch.delete(database.collection("signs").doc(id));
                      }

                      // Commit the batch
                      batch.commit();





                      share|improve this answer




























                        1














                        You should be able to do that using batch, with a code that should look something like the following:



                        // start a batch
                        var batch = database.batch();

                        for (let id of self.signIds) {
                        // for each, add a delete operation to the batch
                        batch.delete(database.collection("signs").doc(id));
                        }

                        // Commit the batch
                        batch.commit();





                        share|improve this answer


























                          1












                          1








                          1







                          You should be able to do that using batch, with a code that should look something like the following:



                          // start a batch
                          var batch = database.batch();

                          for (let id of self.signIds) {
                          // for each, add a delete operation to the batch
                          batch.delete(database.collection("signs").doc(id));
                          }

                          // Commit the batch
                          batch.commit();





                          share|improve this answer













                          You should be able to do that using batch, with a code that should look something like the following:



                          // start a batch
                          var batch = database.batch();

                          for (let id of self.signIds) {
                          // for each, add a delete operation to the batch
                          batch.delete(database.collection("signs").doc(id));
                          }

                          // Commit the batch
                          batch.commit();






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Jan 2 at 0:07









                          quirimmoquirimmo

                          7,66811334




                          7,66811334






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53999827%2fhow-to-wait-for-promise-to-resolve-before-returning-a-new-promise%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              MongoDB - Not Authorized To Execute Command

                              in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

                              Npm cannot find a required file even through it is in the searched directory