1

I get "bookid not found" from my code. I can add author and titles separately using postman but I can't seem to get the reviewsCreate function to to work, am I missing something? PLS help

my schema

    var mongoose = require('mongoose');

    var reviewSchema = new mongoose.Schema({
        author: {
            type: String,
            required: true
        },
        rating: {
            type: Number,
            required: true,
            min: 0,
            max: 5
        },
        reviewText: { type: String, required: true },
        createdOn: {
            type: Date,
            "default": Date.now
        }
    });

    var titleSchema = new mongoose.Schema({
        title: {
            type: String,
            required: true
        },
        favouredBy: {
            type:[String],
            required: false
        },
        reviews: [reviewSchema]

    });
    var bookSchema = new mongoose.Schema({
        bookAuthor: {
            type: String,
            required: true
        },
        titles: [titleSchema]
    });
    mongoose.model('Book', bookSchema);

   router.post('/books/:bookid/titles/:titleid/reviews',ctrlReviews.reviewsCreate);

    module.exports.reviewsCreate = function(req, res) {
        if (req.params.bookid) {
            Bok
                .findById(req.params.titleid)
                .select('titles')
                .exec(
                    function(err, book) {
                        if (err) {
                            sendJSONresponse(res, 400, err);
                        } else {
                            doAddReview(req, res, book);
                        }
                    }
                );
        } else {
            sendJSONresponse(res, 404, {
                "message": "Not found, bookid required"
            });
        }

    };

    var doAddReview = function(req, res, book, author) {
        if (!book) {
            sendJSONresponse(res, 404, "bookid not found");
        } else {
            book.reviews.push({
                author: author,
                rating: req.query.rating,
                reviewText: req.query.reviewText
            });
            book.save(function(err, book) {
                var thisReview;
                if (err) {
                    sendJSONresponse(res, 400, err);
                } else {
                    updateAverageRating(book._id);
                    thisReview = book.reviews[book.reviews.length - 1];
                    sendJSONresponse(res, 201, thisReview);
                }
            });
        }
    };

this is what i get when i used your recommendation error :

TypeError: Cannot read property 'push' of undefined

when i put console.log(book); right under the doAddrivew function.

    { _id: 58dd21c3cb77090b930b6063,
      titles:
       [ { title: 'this is title',
           _id: 58dd3f2701cc081056135dae,
           reviews: [],
           favouredBy: [Object] },
         { title: 'this is the second tittle',
           _id: 58dd42a59f12f110d1756f08,
           reviews: [],
           favouredBy: [Object] } ] 
    }
1
  • Your book schema doesn't have a reviews property. Commented Mar 30, 2017 at 17:13

1 Answer 1

3

your book schema have the titles property which further have the reviews

do

var doAddReview = function(req, res, book, author) {
    if (!book) {
        sendJSONresponse(res, 404, "bookid not found");
    } else {
       /* book.titles.reviews.push({  
            author: author,
            rating: req.query.rating,
            reviewText: req.query.reviewText
        }); */
        book.titles[0].reviews.push({ // to push in first element
            author: author,
            rating: req.query.rating,
            reviewText: req.query.reviewText
        });
        book.save(function(err, book) {
            var thisReview;
            if (err) {
                sendJSONresponse(res, 400, err);
            } else {
                updateAverageRating(book._id);
                // -----------------------------
                thisReview = book.reviews[book.reviews.length - 1];
               // thisReview = book.titles.reviews[book.titles.reviews.length - 1];
                // here also you may have to modify
                sendJSONresponse(res, 201, thisReview);
            }
        });
    }
}

UPDATE


  1. First of All the book should be an instance of your Book Model.
  2. The titles property defined inside bookSchema is an array, So when you want to add the data in bookSchema, bookAuthor property will have just a string, but the titles field would contain objects like [{}, {}, {}], so you have to select the index of titles like titles[0] or titles[1] and then push onto which title you want to review

Note: as reviews of [reviewSchema] is also an array you have use index and select the required element from that array, to perform operations like update, delete like book.titles[0].reviews[1]

Suppose if i want to Push in titles array first element

book.titles[0].reviews.push({
    author: author,
    rating: req.query.rating,
    reviewText: req.query.reviewText
});

    { _id: 58dd21c3cb77090b930b6063,
      titles:
       [ { title: 'this is title',
           _id: 58dd3f2701cc081056135dae,
           reviews: [],
           favouredBy: [Object] },
         { title: 'this is the second tittle',
           _id: 58dd42a59f12f110d1756f08,
           reviews: [],
           favouredBy: [Object] } ] 
    }

Here as you have 2 objects inside the titles you have to select in which you want to push,

if you want to push the reviews in first object of _id: 58dd3f2701cc081056135dae, then select titles[0]

and for _id: 58dd42a59f12f110d1756f08, titles[1]

as your array will have multiple objects, so you have to match the object in which you want to perform the operation like update, so to filter the document you can make the use of $ positional operator

https://docs.mongodb.com/v3.2/reference/operator/update/position/

Please have a look at dot notation also https://docs.mongodb.com/manual/core/document/#dot-notation

Sign up to request clarification or add additional context in comments.

1 Comment

i did that but i get this error Cannot read property 'push' of undefined { _id: 58dd21c3cb77090b930b6063, titles: [ { title: 'this is title', _id: 58dd3f2701cc081056135dae, reviews: [], favouredBy: [Object] }, { title: 'this is the second tittle', _id: 58dd42a59f12f110d1756f08, reviews: [], favouredBy: [Object] } ] } i wanted to push a review to the first title of the book.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.