Smooth
Smooth

Reputation: 956

How to make an array map iteration synchronous?

My current implementation doesn't work because the console.log for "after" is executing before the .map iteration on querySnapshop.docs has finished. In my console I see "before", "after", and then "removing..."

How do I rework this to have the correct execution order?

const uid = this.afAuth.auth.currentUser.uid;
let pollIds = polls.map(poll => poll.payload.doc.id);

console.log("before", pollIds);

var db = firebase.firestore();
db.collection('votes').where('uid', '==', uid).get({source: 'server'}).then((querySnapshot) => {
  let totalVotes = querySnapshot.docs.length;
  let alreadyVoted = querySnapshot.docs.map(async vote => {
    vote.ref.get().then(doc => {
      let pollId = doc.data().poll
      var index = pollIds.indexOf(pollId);
      if (index > -1) {
        console.log("removing...", pollIds[index]);
        pollIds.splice(index, 1);
      }

    });
  });
  console.log("after", pollIds);
});

Upvotes: 0

Views: 446

Answers (1)

fjc
fjc

Reputation: 5815

You can easily rewrite your code using async/await. It will become easier to read, to write, to maintain, plus it will log your after message as wished.

(async () => {
    console.log('before', pollIds);

    const uid = this.afAuth.auth.currentUser.uid;
    const pollIds = polls.map(poll => poll.payload.doc.id);


    const db = firebase.firestore();
    const querySnapshot = await db.collection('votes').where('uid', '==', uid).get({source: 'server'});
    const docs = querySnapshot.docs;
    const totalVotes = docs.length;

    for (const vote of docs) {
        const doc = await vote.ref.get();
        const pollId = doc.data().poll;
        const index = pollIds.indexOf(pollId);
        if (index > -1) {
            console.log('removing...', pollIds[index]);
            pollIds.splice(index, 1);
        }
    }

    console.log('after', pollIds);
})();

I have obviously not tried the actual code, so take it as inspiration.

Upvotes: 1

Related Questions