0

I`m using Firestore as database and VueJS as Javascript framework.

The goal:

  1. I got one collection where all fotball players are represented by individual documents. I get a list of all available fotball players.

  2. Get all statistics that exists on available fotball players.

  3. Combine (aggregate) all statistics for per fotball player for all matches played.

The problem is that this.aggregatedPlayerStats returns as an empty array. I suspect it has to do with asynchronous code, as it works if I trigger the aggregatePlayerStats() method on a button.

Code:

export default {
  name: "AggregatedAllTimeStats",
  data() {
    return {
      allPlayers: [],
      allStats: [],
      aggregatedPlayerStats: []
    };
  },
  async created() {
    await this.getAllPlayers();
    await this.getAllStats();
    this.aggregatePlayerStats();

  },
  methods: {
    async getAllPlayers() {
      return db.collection("players").get().then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
          this.allPlayers.push({
            playerid: doc.id,
            name: doc.data().name,
            playerstatus: doc.data().playerstatus
          })
        })
      })
    },
    getAllStats() {
      this.allPlayers.forEach((player) => {
        return db.collection("playerstatsformatch").where("playerid", "==", player.playerid).get().then((querySnapshot) => {
          querySnapshot.forEach((doc) => {
            this.allStats.push(doc.data())
          })
        })
      })
    },
    aggregatePlayerStats() {
      const aggregatedResults = Object.values(
        this.allStats.reduce((a, c) => {
          if (!a[c.playerid]) {
            a[c.playerid] = {
              goals: c.goals,
              name: c.name,
              assists: c.assists

            };
          } else {
            a[c.playerid].goals += c.goals;

          }
          return a;
        }, {})
      );
      this.aggregatedPlayerStats = aggregatedResults
      console.log(this.aggregatedPlayerStats)
    }
  },
};
2
  • unclear how you expect to return from a forEach. Commented Jul 5, 2022 at 13:24
  • Also, if you're using the keyword async, an await is expected rather than a .then. Commented Jul 5, 2022 at 13:41

1 Answer 1

1

Your getAllStats doesn't return any promise from its outer loop, so there's nothing to await for when calling it. As always, the solution to wait for multiple promises is to use Promise.all.

This should be closer:

getAllStats() {
  return Promise.all(this.allPlayers.map((player) => {
    return db.collection("playerstatsformatch").where("playerid", "==", player.playerid).get().then((querySnapshot) => {
      querySnapshot.forEach((doc) => {
        this.allStats.push(doc.data())
      })
    })
  }))
},
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome, you are right. I will need to read up on Promise.all :) Thanks Frank!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.