1

I am trying to update the review average of an recipe whenever a user submits a review of a recipe. Here is both the files that store the model schema for Recipes and Reviews.

Here is review.js

const express = require('express');
const mongoose = require('mongoose');
const User = require('../model/user');
require('mongoose-currency').loadType(mongoose);
const Currency = mongoose.Types.Currency;
const Schema = mongoose.Schema;

let reviewSchema = new Schema();

reviewSchema.add({


    rating: {
        type: Number,
        min: 1,
        max: 5,
        defualt: 0
    },


    howEasyToMake: {
        type: Number,
        required: true,
        min: 1,
        max: 5
    },

    howGoodTaste: {
        type: Number,
        required: true,
        min: 1,
        max: 5,
    },

    wouldMakeAgain: {
        type: Number,
        required: true,
        min: 1,
        max: 5,
    },


    comment: {
        type: String,
        default: ""
    },


    postedBy: {
        type: String,
        required: true,
        index: true
    },

    reviewOf: {
        type: String,
        required: true,
        index: true
    },

    postersCreationDate: {
        type: Number,
        required: true
    },

    chefsCreationDate: {
        type: Number,
        required: true
    },

    chefsId: {
        type: String
    }


});

module.exports = reviewSchema;

And here is recipe.js

const express = require('express');
const mongoose = require('mongoose');
const User = require('../model/user');
require('mongoose-currency').loadType(mongoose);
const Currency = mongoose.Types.Currency;
const Schema = mongoose.Schema;
const reviewSchema = require('../model/review');



let recipeSchema = new Schema({

  name: {
    type: String,
    required: true
  },

  description: {
    type: String,
  },

  steps: {
    type: String,
    required: true,
  },

  ingredients: {
    type: Array,
    default: ['1', '2', '3', '4']
  },

  category: {
    type: String,
    required: true,
    index: true
  },

  postedBy: {
    type: String,
    required: true,
  },


  reviewsOfRecipe: [reviewSchema],

  numberOfRatings: {
    type: Number,
    default: 0
  },

  totalAddedRatings: {
      type: Number,
      default: 0
  },

  reviewAverage: {
      type: Number,
      default: 0
  },



  postersCreationDate: {
    type: Number,
    index: true
  },

  likedBy: {
      type: Array

  },

  reviewedBy: {
      type: Array
  }


});


let Recipe = mongoose.model('Recipe', recipeSchema);

module.exports = Recipe;

In recipe.js I clearly have numberOfRatings, rating, and totalAddedRatings.js as being numbers. I do the same for wouldMakeAgain, howEasyToMake and howGoodTaste in review.js.

Problems arise whenever I try to update my recipe document when someone submits a review.

These specific lines of code don't seem to work. I should note that within this block of code, recipe refers to the model instance of the recipe that I get from Recipe.findOne({name: req.params.name}). And when I console.log(recipe) in this part of the code, it prints out the recipe. So I have the model instance, the problem is that I am unable to update it. Here are the lines in question that don't seem to work.

recipe.update({$inc: {numberOfRatings: 1}});


                recipe.save(function (err) {
                    if (err) return handleError(err);
                    console.log('Success!');
                });

            recipe.update({$inc: {totalAddedRatings: reviewScore}});

            recipe.save(function (err) {
                if (err) return handleError(err);
                console.log('Success!');
            });

numberOfRating and totalAddedRatings are not being incremented like they are supposed to.

And here, I try to calculate the new review average for the recipe...

let newAverage = Number(req.body.totalAddedRatings) / Number(req.body.numberOfRatings);

When I console.log(typeof(newAverage));, I get number. So JS is telling me that it's a number. But when I try to do this,

        recipe.update({$set: {reviewAverage: newAverage}});

        recipe.save(function (err) {
            if (err) return handleError(err);
            console.log('Success!');
        });

I get the following error:

(node:2352) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): CastError
: Cast to number failed for value "NaN" at path "reviewAverage"

Can anyone explain to me what I am doing wrong? Am I not supposed to use $set with numbers?

UPDATE: I tried making a few changes in hopes of resolving this issue but I get the same results.

I tried to do this instead...

        let newAverage = Number(req.body.totalAddedRatings) / Number(req.body.numberOfRatings);

        let numAverage = Number(newAverage);

  recipe.update({$set: {reviewAverage: numAverage}});

        recipe.save(function (err) {
            if (err) return handleError(err);
            console.log('Success!');
        });

However doing so gave me the same error message. When I console.log(typeof(numAverage));, it prints out number. Strangely, however, when I console.log(numAverage));, I get NaN.

I also tried doing this and I still got the error:

recipe.set('reviewAverage', numAverage);
MountainSlayer
  • 291
  • 1
  • 5
  • 14

0 Answers0