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");
});
});
Related
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
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}
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;
There is a array of user IDs in currentUser.follow. Each user has posts with referenceId of PostSchema . Now I want to populate each user's post and store it in an array[userArray]. But due to scope issue the array remains empty. Please show me how I can get all the users with their post in the Array[userArray]
app.js
app.get("/", isLoggedIn, function(req, res){
var currentUser =req.user;
var userArray=[];
for(let fol of currentUser.follow){
User.findById(fol).populate("posts").exec(function(err, user){
if(err){
console.log(err);
}else{
console.log(user); // a user with populated posts
userArray.push(user);
console.log(userArray); //stores user but posts is not populated
}
});
}
console.log(userArray); // empty array
});
User Schema
var mongoose =require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var UserSchema = new mongoose.Schema({
name: String,
email: String,
username: String,
password: String,
posts: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Post"
}
],
follow: [String]
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSchema);
Post Schema
var mongoose =require("mongoose");
var PostSchema = new mongoose.Schema({
text: String,
image: String,
author:{
id:{
type: mongoose.Schema.Types.ObjectId,
ref : "User"
},
username: String
},
createdAt: {type:Date, default:Date.now}
});
module.exports= mongoose.model("Post", PostSchema);
Because User.findById is asynchronous so the second console.log(userArray); will excute before the result pushed to userArray.
There is a better way to do this with $in operator and async/await:
app.get("/", isLoggedIn, async function(req, res){
try {
var currentUser = req.user;
var userArray = await User.find({_id: {$in: currentUser.follow}}).populate("posts");
console.log(userArray);
} catch(err) {
console.log(err);
}
});
I am new to express/mongoose and trying to implement User-Post relationship.Aka 1:Many.
I have two models,
// *models/user.js
var mongoose = require('mongoose');
var userSchema = mongoose.Schema({
email: {type: 'string'},
password: {type: 'string'},
posts: [{type: mongoose.Schema.Types.ObjectId, ref: 'Post'}]
});
module.exports = mongoose.model('User', userSchema);
// *models/post.js
var mongoose = require('mongoose');
var postSchema = mongoose.Schema({
user : { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
body: String,
title: String
});
module.exports = mongoose.model('Post', postSchema);
server.js,
Post = require('./models/post');
User = require('./models/user');
app.post('/api/posts',(req,res)=>{
User.findOne({email: "valid_email"},(err, user)=>{
var post = {
title: "Post 1 Title",
body: "Post 1 body",
user: user._id
}
Post.create(post, (err, post)=>{
res.send(post);
});
});
});
Now, this approach is working for saving the Post which belongs to user with email "valid_email".I can reach out it's user by populating.
app.get('/post', (req,res)=>{
Post.findOne(title: "Post 1 title")
.populate('user')
.exec(function (err, user) {
if (err) throw err;
console.log(user._id, user.email);
res.end();
});
});
I thought generating a Post in the callback of finding a User would automatically push it to User's posts.Not only it is not how it works, i can't push manually to "user.posts".
It says can't "push" to undefined.When i console.log(user.posts) i get undefined.
How is it that i can generate a Post belongsTo a User, then i can populate the user just by it's id, but can't push a Post to User? It gives undefined "user.posts" ?
!!! I got it working.
app.post('/api/posts', (req,res)=>{
User.findOne({id: _some_user_id}, (err,user)=>{
var poster = user;
var post = {title: req.body.title, body: req.body.body, category: req.body.category, user: poster}
Post.create(post, (err,post)=>{
res.send(post);
poster.posts.push(post);
poster.save();
});
});
});