kRAk3N kRAk3N - 4 months ago 15
Node.js Question

var access error inside findOne in forEach nodejs

api.get('/evaluateproductratings', function(req, res){
Product.find({}, function(err, results){
results.forEach(function(product){
var rate = math.divide(0.0,1);
var count = math.add(0,0);

product.Ingredients.split(", ").forEach(function(ingredient){
Ingredient.findOne({title: ingredient}, function(err, ing){

if(err) {
console.log(err);
}
else if(!ing){
rate = math.add(rate, 0.0);
count = math.add(count, 1);
}
else{
rate = math.add(rate, ing.Weightage);
count = math.add(count, 1);
}
})
})
var finalrate = math.divide(rate,count);
console.log(finalrate);
product.update({$set:{'Rating': finalrate}}, function(err, result){
if(err){
console.log(err);
}
else{
console.log('product rated successfully.');
}
})
})
res.json('all products rated successfully');
})
})


the problem occurring here is that i'm not able to update the variables rate and count inside Ingredient.findOne and hence finalrate is always evaluated to NaN (i.e., 0/0) since both rate and count were initialized to 0 for every product.

ProductSchema :

title:"something",
Ingredient:"ing1, ing2, ing3"


IngredientSchema :

title:"ing1",
Weightage:"2"

title:"ing2",
Weightage:"5"

title:"ing3",
Weightage:"7"


how to solve this?

Answer

You need to move your update function into your Ingredient.findOne() callback, otherwise your rate and count values won't be updated to their new values. Your update function was outside your Ingredient.findOne() callback which means that your Ingredient.findOne() and product.update() were executing at the same point in the flow, your update statement would've never been able to know what your rate and count were updated to in this case.

api.get('/evaluateproductratings', function(req, res){
    Product.find({}, function(err, results){
      results.forEach(function(product){
          var rate = math.divide(0.0,1);
          var count = math.add(0,0);

          product.Ingredients.split(", ").forEach(function(ingredient){
            Ingredient.findOne({title: ingredient}, function(err, ing){

              if(err) {
                console.log(err);
              }
              else if(!ing){
                rate = math.add(rate, 0.0);
                count = math.add(count, 1);
              }
              else{
                  rate = math.add(rate, ing.Weightage);
                  count = math.add(count, 1);          
              }

              var finalrate = math.divide(rate,count);
              console.log(finalrate);
              product.update({$set:{'Rating': finalrate}}, function(err, result){
                if(err){
                  console.log(err);
                }
                else{
                  console.log('product rated successfully.');

                  return res.json('all products rated successfully');
                }
              });
            });
          });

        });

    });
});       
Comments