0
app.get('/ratings', function (req, res){ 
 db.database.find({rating:5}).count(function(err, doc) {
  review.FiveStarCount=doc;
 });        
 db.database.find({rating:4}).count(function(err, doc) {
  review.FourStarCount=doc;
 });

I am new to using the MEAN stack and trying to return the values of the number of 5 and 4 star reviews. I can retrieve the number of 5 stars just fine, but when I do multiple , I seem to be running into trouble and not sure how to set it up.

Vohn
  • 11
  • 1
  • *I seem to be running into trouble* Can you elaborate ? – Rayon Nov 03 '15 at 03:49
  • Though I can't tell by looking at your code..find is an async function - the callbacks are not executed in the order you wrote them, they happen at arbitrary times. If you do not use a latch or a promise (or nested callbacks) you will not be able to retrieve both. Please share more of your code – Jonah Williams Nov 03 '15 at 03:50

2 Answers2

0

You kind of need to get the gist of how to handle control flow while doing async operations. The function execution would not stop, unlike php, when you are running an async operation. To accomplish what you are trying to do, the second db call needs to be inside the callback of the first. Try this out.

app.get('/ratings', function (req, res, next) { 
db.database.find({rating:5}).count(function(err, doc) {
    // always handle error first
    if (err) {
        return next(err);
    }

    if (doc) {
        review.FiveStarCount = doc;
    }

    db.database.find({rating:4}).count(function(err, doc) {
        if (err) {
            return next(err);
        }

        if (doc) {
            review.FourStarCount = doc;
        }

        console.log(review.FiveStarCount, review.FourStarCount);
    });
});

});

Swaraj Giri
  • 4,007
  • 2
  • 27
  • 44
0

So it seems like you are running against the async nature of JavaScript. in the case of the functions above, they will not execute in the order you have written (and you wouldn't want them too!) because they are async. There are few simple solutions to get you going while you learn more about the problem.

Solution 1: Nested callbacks. Hard to read. also, it waits for the first to complete before firing the second, possibly slowing everything down.

app.get('/ratings', function(req, res) { 
  var review = {};
  db.database.find({rating:5}).count(function(err, doc) {
  review.FiveStarCount = doc;

  db.database.find({rating:4}).count(function(err, doc) {
    review.FourStarCount = doc;

    // DO something with data
    res.json(review);
  });
});

Solution 2: Latch. This has the advantage of making the requests in parallel and not being as awful to read.

app.get('/ratings', function(req, res) {
  var review = {};

  db.database.find({rating:5}).count(function(err, doc) {
    review.FiveStarCount=doc;

    if (review.FiveStarCount && review.FourStarCount) {
      // DO something here
      // Will only execute if the other has finished 
    }
  });        

  db.database.find({rating:4}).count(function(err, doc) {
    review.FourStarCount=doc;

    if (review.FiveStarCount && review.FourStarCount) {
      // DO something here
      // Will only execute if the other has finished 
    }
  });

});

There are course more solutions, such as maybe a better query or promises. Maybe read a bit more about async JavaScript here to get a better understanding.

Community
  • 1
  • 1
Jonah Williams
  • 20,499
  • 6
  • 65
  • 53