3

In my vuetify/vue.js appliction, i'm trying to read a firestore collection I've stored to calculate an average rating from all ratings stored there:

function updateRating() {
  let firestoreQuery = firebase
      .firestore()
      .collection('ratings')
      .where('qrCodeId', '==', this.qrCode.id);

  let ratingsSum = 0;
  let ratingsAmountCounter = 0;

  firestoreQuery.get().then(querySnapshot => {
    querySnapshot.forEach(doc => {
      ratingsSum += doc.rating;
      ratingsAmountCounter++;
    });
  });
}

However, I can't access the ratingsSum and ratingsAmountCounter variables from inside my forEach arrow function. I've already tried using this or the var _this = this workaround, but both don't seem to work and eslint still reports:

'ratingsSum' is assigned a value but never used (no-unused-vars)

What am I doing wrong?

RobC
  • 22,977
  • 20
  • 73
  • 80
  • 3
    Accessing the variables like this looks ok. But since `firestoreQuery.get()` is **asynchronous**, it's unclear to me how/when you want to *read* `ratingsSum` and `ratingsAmountCounter`. The fact that you are using an arrow function is irrelevant. – Felix Kling Jan 19 '20 at 13:17
  • @FelixKling hm, I haven't considered that - I wanted to increment them in the foreach to calculate the average value afterwards – Bas von Bassadin Jan 19 '20 at 13:19
  • 1
    You can do that... inside the `.then` callback. You can also *call* other functions and pass the average to it. But you cannot *return* the average value from `updateRating`. The best you can do is return the promise that `firestoreQuery.get().then(...)` returns. – Felix Kling Jan 19 '20 at 13:21
  • @FelixKling Yeah, I see what you're getting at - it seems like my original question is off-topic after all, then... I'll try to update it with my newest progress – Bas von Bassadin Jan 19 '20 at 13:27

2 Answers2

1

As the comments suggest, the problem here is that you have no code that actually reads ratingsSum and ratingsAmountCounter. The error message is telling you that ESLint has triggered on the rule called "no-unused-vars" to tell you about this. Variables that are never read are probably a bug, or at least unnecessary code.

What you should probably do is return a promise to the caller so that they can get a hold of the values, whenever the asynchronous get() is complete and the values are computed. For example:

function updateRating() {
  let firestoreQuery = firebase
      .firestore()
      .collection('ratings')
      .where('qrCodeId', '==', this.qrCode.id);

  let ratingsSum = 0;
  let ratingsAmountCounter = 0;

  return firestoreQuery.get().then(querySnapshot => {
    querySnapshot.forEach(doc => {
      ratingsSum += doc.rating;
      ratingsAmountCounter++;
    });
    return { ratingsSum, ratingsAmountCounter }
  });
}

The caller of this function now receives a promise that resolves when the values are known, and they can be fetched out of the resolved object:

updateRating().then(result => {
  const { ratingsSum, ratingsAmountCounter } = result;
  // Now you can use ratingsSum and ratingsAmountCounter...
})
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
0

this might work, I have no way to test it since I don't know how to use vue but here goes

   async function getData(){
      return await firebase
          .firestore()
          .collection('ratings')
          .where('qrCodeId', '==', this.qrCode.id)
          .get()
        }
    })

you can then do this:

getData().then(_querySnapshot => {
        var ratingsSum = 0
        var ratingsAmountCounter = 0
      _querySnapshot.forEach(doc => {
        ratingsSum += doc.rating;
        ratingsAmountCounter++;
      });
});
Raphael Castro
  • 907
  • 1
  • 8
  • 26
  • Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Jan 19 '20 at 17:13