Mongoose Populate when using ObjectId not working - javascript

New to mongoose! I want to get all orders and populate each order with the product schema. However when I test the route no information comes through when I have the products type as ObjectId. How can I find all orders , populate the order with its products, then print it out?
Get All Orders route
const express = require('express');
const router = express.Router();
const {Order}=require('../models/order.js');
router.get('/', (req, res) => {
Order.find({})
.populate({path:'products', select:'name'})
.then((orders)=>{
res.json(orders);
})
.catch((err)=>{
res.json(err);
});
});
order.js
const mongoose = require('mongoose');
const Schema= mongoose.Schema;
const productSchema = new mongoose.Schema(
{
name: String,
price: Number,
category: String
},
{ timestamps: true }
);
const orderSchema = new mongoose.Schema(
{
date: {
type:Date,
default: Date.now},
customerName: String,
customerAddress: String,
creditCard: Number,
products:[{
type: Schema.Types.ObjectId, ref:'product'
}]
},
{ timestamps: true }
);
const Order = mongoose.model('Order', orderSchema);
const Product = mongoose.model('product', productSchema);
module.exports = {
Order:Order,
Product:Product}

Related

Express/mongoose returns empty array when trying to get request

I am trying to get the list of books from the database. I inserted the data on mongoose compass. I only get an empty array back.
//Model File
import mongoose from "mongoose";
const bookSchema = mongoose.Schema({
title: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
releasedDate: {
type: String,
required: true,
},
});
const Book = mongoose.model("Book", bookSchema);
export default Book;
//Routes file
import express from "express";
import Book from "./bookModel.js";
const router = express.Router();
router.get("/", async (req, res) => {
const books = await Book.find({});
res.status(200).json(books);
});
make sure you have books data in db.if it is there then try to add then and catch blocks to your code. Then you will get to know what is the error.
await Book.find({})
.then((data) =>{
res.send(data)
})
.catch((err) =>{
res.send(err)
})
When you create your model, change mongoose.model by new Schema and declare _id attribute like:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const Book = new Schema({
_id: { type: Schema.ObjectId, auto: true },
// other attributes
})
Update: If it doesn't seem to work, try changing _id with other names such as bookID or id, that can be the error, read https://github.com/Automattic/mongoose/issues/1285

Monggose array schema type not passing more than one items

I am trying to pass an array of schemas that will populate multiple social media documents in the qrCode document but when I send the post request using Postman it only sends 1 of them.
This is the QrCode Modle where the shcema is being defined
const Joi = require("joi");
const mongoose = require("mongoose");
const { themeSchema } = require("./Theme");
const { userSchema } = require("./User");
const { socialSchema } = require("./Social");
const QrCode = mongoose.model(
"QrCode",
new mongoose.Schema({
user: {
type: userSchema,
required: true,
},
name: {
type: String,
maxLength: 255,
required: true,
trim: true,
},
theme: {
type: themeSchema,
required: true,
},
// Social Media Links
social: [
{
type: socialSchema,
required: true,
},
],
})
);
function ValidateQrCode(qrCode) {
const schema = {
userId: Joi.objectId(),
name: Joi.string().max(255).required(),
themeId: Joi.objectId().required(),
socialId: Joi.array().required().items(Joi.string()),
};
return Joi.validate(qrCode, schema);
}
module.exports.QrCode = QrCode;
module.exports.validate = ValidateQrCode;
This is the post route to create a new qrCode
const { QrCode, validate } = require("../models/QrCode");
const { Theme } = require("../models/Theme");
const { User } = require("../models/User");
const { Social } = require("../models/Social");
const auth = require("../middleware/auth");
const express = require("express");
const router = express.Router();
router.get("/", async (req, res) => {
const qrCodes = await QrCode.find().sort("-name");
res.send(qrCodes);
});
router.post("/", auth, async (req, res) => {
const { error } = validate(req.body);
if (error) res.status(400).send(error.details[0].message);
const theme = await Theme.findById(req.body.themeId);
if (!theme) return res.status(400).send("Invalid theme.");
const social = await Social.findById(req.body.socialId);
if (!social) return res.status(400).send("Invalid social.");
const user = await User.findById(req.user._id);
if (!user) return res.status(400).send("Invalid theme.");
const qrCode = new QrCode({
user: user,
name: req.body.name,
theme: theme,
social: social,
});
await qrCode.save();
res.send(qrCode);
});
module.exports = router;
This is the postman post request that I send
{
"name": "Test399",
"themeId": "60f607ab97943dfaa05811bc",
//the ID's for all the socials
"socialId": ["60f657f97f90bb0cd10cfef1", "60f77d179b05d91894ef32ab"]
}
Your route has
const social = await Social.findById(req.body.socialId);
here you are trying to pass array and Mongoose findById document says to send the _id for query, that is the reason mongoose gives only one value.
Iterate over the array and get values before sending the response.

Menu API data not showing

I am trying to make API for sample Menu Data in which the data must be fetched and shown by entering Restaurant ID. Controller, Model and Router is set but I load it in Postman the data is not showing also if I console.log() the result, its showing an empty array. Please share your ideas. Thanks in advance.
Controller (Menu.js)
const Menu = require('../Models/Menu');
exports.getMenu = (req, res) => {
Menu.find({
restID: req.params.restID
}).then(result => {
res.status(200).json({
menus: result,
message: "Menu Data Success"
});
console.log(result);
}).catch(error => {
res.status(500).json({
message: error
});
})
}
Model (Menu.js)
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const MenuSchema = new Schema({
item: {
type: String,
required: true
},
cost: {
type: Number,
required: true
},
description: {
type: String
},
restID: {
type: Number,
required: true
}
});
module.exports = mongoose.model('menus', MenuSchema, 'Menu');
Router (router.js)
const express = require('express');
const MenuController = require('../Controllers/Menu');
const router = express.Router();
router.get('/restaurantMenu/:restID',MenuController.getMenu);
module.exports = router;

NodeJS - returning undefined issue

Trying to create a blog website where users can comment on posts. I was able to create different blog posts so now I am trying to implement the comment feature. In my routes/admin/comments.js file I was able to create a comments array and append each comment into the array. I am using EJS to try to display the comments which should be <%=comments%> but I am getting an error that says 'comments is not defined' even though I have defined it in:
Comment.find({})
.then(comments =>{
console.log(comments)
res.render('home/post', {comments})
})
})
What am i doing wrong? I am following the same method I did with creating posts.
models/Post.js Schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const PostSchema = new Schema({
title:{
type: String,
required: true
},
description:{
type: String,
required: true
},
body:{
type: String,
required: true
},
comments:[{
type: Schema.Types.ObjectId,
ref: 'comments'
}]
},{usePushEach:true})
module.exports = mongoose.model('posts', PostSchema);
models/Comment.js Schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const CommentSchema = new Schema({
username:{
type: String,
required: true,
},
body:{
type: String,
required: true
},
})
module.exports = mongoose.model('comments', CommentSchema)
routes/admin/comments.js file
const express = require('express');
const router = express.Router();
const Post = require('../../models/Post');
const Comment = require('../../models/Comment');
router.get('/', (req,res) =>{
Comment.find({})
.then(comments =>{
console.log(comments)
res.render('home/post', {comments})
})
})
//Finds the comments and makes it available as object
router.post('/', (req,res) =>{
Post.findOne({_id: req.body.id})
.then(post=>{
console.log(post)
const newComment = new Comment({
username: req.body.username,
body: req.body.body,
});
post.comments.push(newComment);
post.save()
.then(savedPost =>{
newComment.save()
.then(savedComment =>{
res.redirect('/')
})
})
})
})
module.exports = router;

Mongoose save one to many

I have following model in mongoose in which blog have many comments
var mongoose = require('mongoose')
, Schema = mongoose.Schema
var blogScheam = Schema({
title: String,
comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }]
});
module.exports = mongoose.model('Post', blogScheam);
Comment Model
var mongoose = require('mongoose')
, Schema = mongoose.Schema
var commentSchema = Schema({
comment: String,
user: { type: Schema.Types.ObjectId, ref: 'User' }
});
module.exports = mongoose.model('Comment', commentSchema);
USER SCHEMA
var mongoose = require('mongoose')
, Schema = mongoose.Schema
var userScheam = Schema({
name: String,
age: Number,
posts: [{ type: Schema.Types.ObjectId, ref: 'Post' }]
});
module.exports = mongoose.model('User', userScheam);
I am using following function to save the comment in related blog post. I am able to save the comment but comment is saved as embedded document while I am expecting that blog should only have _id
app.post('/comment', (req, res) => {
Blog.findById({ _id: req.body._id }).then(blog => {
var comment = new Comment({
comment: req.body.title
})
blog.comments.push(comment2);
blog.save().then(() => {
res.render("details");
}).catch(() => {
res.render("details");
})
});
});
Since the blog schema is expecting the comments fields an array of just comment ids, you would need to save the comment first then push the new comment id to the blog:
app.post('/comment', (req, res) => {
const comment = new Comment({
comment: req.body.title
});
comment.save().then(c => (
Blog.findByIdAndUpdate(req.body._id,{ '$push': { 'comments': c._id } });
)).then(() => {
res.render("details");
}).catch(() => {
res.render("details");
});
});

Categories

Resources