Search code examples
javascriptfirebasevue.jsgoogle-cloud-firestorevuex

1 action 2 commits (mutations), but I have to wait for my first commit to finish loading


my action goes like this:

actions: {
    getFireBaseOrders(state) {
      db.collection(`ordersOptimized`)
        .where("date", ">=", 20210107)
        .onSnapshot((res) => {
          const changes = res.docChanges();
          changes.forEach((change) => {
            let payload = change.doc.data();
            state.commit("firebaseOrders", payload);
          });
        });
        state.commit("shopPerformanceTable")
    },

This stores pushes my firebase stuff to my state.

First mutation goes like this:

firebaseOrders(state, payload) {
  for (let i = 0; i < Object.keys(payload).length - 1; i++) {
    state.firebaseOrders.unshift(payload[i]);
  }

Second mutation goes like this:

shopPerformanceTable(state){
  // console.log(state.firebaseOrders)
  state.shopPerformanceTable = Object.values(
    state.firebaseOrders.reduce((newArray, oldArray) => {
      const key = oldArray.shopname;

      newArray[key] = newArray[key] ?? {
        shopName: oldArray.shopname,
        orders: 0,
        revenue: 0,
        pendingOrders: 0,
      };

      newArray[key].orders++;
      newArray[key].revenue += oldArray.subtotal;

      if (oldArray.statuses == "pending") {
        newArray[key].pendingOrders++;
      }

      return newArray;
    }, {})
  );
  // console.log(state.shopPerformanceTable);
},

The problem is, they run synchronously that means on the second mutation, state.firebaseOrders is still an empty array and will return and empty array. How do I wait for my mutation firebaseOrders finish first before running the shopPerformanceTable mutation?


Solution

  • I don't use Firebase but it looks like your second commit is in the wrong place. Try this:

    getFireBaseOrders(state) {
      db.collection(`ordersOptimized`)
        .where("date", ">=", 20210107)
        .onSnapshot((res) => {
          const changes = res.docChanges();
          changes.forEach((change) => {
            let payload = change.doc.data();
            state.commit("firebaseOrders", payload);
          });
          state.commit("shopPerformanceTable");
        });
    },
    

    This is moving the second commit into the onSnapshot callback, after the forEach has executed.