I have 2 models User & Revive as you can see below... in the router(see below) what is the query to get all revives that belong to the user/creator to display on his dashboard/profile page?
User Model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
}
});
module.exports = mongoose.model('User', userSchema);
Revive Model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var reviveSchema = new Schema({
reviveTitle: {
type: String,
required: true
},
reviveStory: {
type: String
},
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
}
}
});
module.exports = mongoose.model('Revive', reviveSchema);
Router:
router.get('/dashboard', isLoggedIn, function(req, res) {
code ?? to get all revives that belong to the creator/user only ??
res.render('users/dashboard', {currentUser: req.user});
});
Well, I would setup the Revive schema bit differently:
author: { type: mongoose.Schema.Types.ObjectId, ref: "User"}
Then you should be able to just do a proper find:
const Revive = mongoose.model('Revive');
router.get('/dashboard', isLoggedIn, function(req, res) {
Revive.find({author:req.user._id}, (e, revives) => {
// however you handle errors goes first
res.render('users/dashboard', {currentUser: req.user, revives: revives});
});
});
Related
I have two schema:
(1) authSchema
(2) bookSchema
const authSchema = new mongoose.Schema({
name: {
type: String,
required: true
}
});
const bookSchema = new mongoose.Schema({
authors: [{
authId: {
type: Schema.Types.ObjectId,
ref: "auth",
required: true
}
}],
title: {
type: String,
required: true,
}
});
And my get route
// Auth = new mongoose.model("auth", authSchema);
app.get("/", (req, res, next) => {
Auth.find({})
.select({
__v: 0,
_id: 0,
})
})
Then the output is:
pastebin link
*** But I want to data the below format
pastebin link
What changes make this output!
thanks!
I know, this is one of the popular questions out there. On populate I expect it to return the user with his posts, but it's returning an empty array of posts.
Here is my User model.
User.js
const mongoose = require("mongoose")
const Schema = mongoose.Schema
const userSchema = new Schema({
username: { type: String, required: true },
email: { type: String, required: true },
password: { type: String, required: true },
posts: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Post"
}]
}, { timestamps: true })
const User = mongoose.model("User", userSchema)
module.exports = User
Post.js
const mongoose = require("mongoose")
const Schema = mongoose.Schema
const postSchema = new Schema({
postTitle: { type: String, required: true },
postDescription: { type: String, required: true },
user: { type: Schema.Types.ObjectId, ref: "User" },
}, { timestamps: true }
)
const Post = mongoose.model("Post", postSchema)
module.exports = Post
router.get("/posts/:id", usersController.getUserPosts)
usersController.js
getUserPosts: (req, res) => {
User.findById(req.params.id).populate("posts").exec((err, posts) => {
if (err) console.log(err)
console.log(posts)
})
}
I'm getting this:
{ posts: [],
_id: 5e4e3e7eecd9a53c185117d4,
username: 'rick',
email: 'rick#gmail.com',
createdAt: 2020-02-20T08:08:30.878Z,
updatedAt: 2020-02-20T08:08:30.878Z,
__v: 0 }
Where am I going wrong?
Below is the code for User model, Post model and the route. I need to query the DB and then pass to the view through the router. What am I missing?
User model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
}
});
module.exports = mongoose.model('User', userSchema);
Posts model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var postSchema = new Schema({
postTitle: {
type: String,
required: true
},
postStory: {
type: String
},
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
}
});
module.exports = mongoose.model('Post', postSchema);
And here is the query in the router that I'm trying but apparently it's not the way to go...
My GET route:
router.get('/dashboard', isLoggedIn, function(req, res) {
Post.find({author:req.user._id}, (err, posts) => {
if(err) {
console.log(err);
} else {
res.render('users/dashboard', {currentUser: req.user, posts: posts});
}
});
});
What am I missing here?
You may want to change the find query to match the proper attribute in the following line:
Post.find({author: req.user._id}, (err, posts) => {
to be:
Post.find({'author.id': req.user._id}, (err, posts) => {
Read more: http://mongoosejs.com/docs/2.7.x/docs/finding-documents.html
I have two similar parent-child relationship trees in my data model and I am using Mongoose's middleware to handle cascade of deletes.
The first hierarchy is represented as follows:
blog hierarchy
//blog.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = require('./user.js');
var Entry = require('./entry.js');
var Follower = require('./follower.js');
var Blog = new Schema({
author: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
name: {
type: String,
required: true
},
headerImageUrl: String,
description: {
type: String,
required: true
}
}, {
timestamps: true
});
Blog.pre('remove', function(next) {
Entry.find({"blogId": this._id})
.exec(function(err, entries) {
console.log("found entries " + entries);
for(var i = entries.length -1; i >= 0; i--) {
entries[i].remove();
}
});
Follower.remove({"blogId": this._id}).exec();
next();
});
module.exports = mongoose.model('Blog', Blog);
//entry.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Blog = require('./blog.js');
var Comment = require('./comment.js');
var Entry = new Schema({
blogId: {
type: Schema.Types.ObjectId,
ref: 'Blog'
},
title: String,
thumbnailUrl: String,
content: String
}, {
timestamps: true
});
Entry.pre('remove', function(next) {
Comment.remove({"entryId": this._id}).exec();
next();
});
module.exports = mongoose.model('Entry', Entry);
//comment.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = require('./user.js');
var Entry = require('./entry.js');
var Post = require('./post.js');
var Comment = new Schema({
text: {
type: String,
required: true
},
postedBy: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
parentComment: this,
entryId: {
type: Schema.Types.ObjectId,
ref: 'Entry'
},
postId: {
type: Schema.Types.ObjectId,
ref: 'Post'
},
type: {
type: String,
enum: ['BLOG', 'FORUM', 'COMMENT'],
required: true
}
}, {
timestamps: true
});
module.exports = mongoose.model('Comment', Comment);
In this case, when remove is called on a blog instance, the Blog.pre('remove'... functionality does what it is intended to do and cleans up all children of the blog instance.
The calling code is as follows:
blogRouter.route('/:blogId')
//delete a specific blog by blog id: [OWNER OR ADMIN USER]
.delete(Verify.verifyOrdinaryUser, Verify.verifyBlogOwnerOrAdmin, function(req, res, next) {
Blog.findById(req.params.blogId, function(err, blog) {
if(err) return next(err);
blog.remove();
res.json(blog);
});
});
I am doing exactly the same thing for the second hierarchy, visually represented here: forum hierarchy and with the following code:
//forum.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = require('./user.js');
var Post = require('./post.js');
var Subscription = require('./subscription.js');
var Forum = new Schema({
title: {
type: String,
required: true
},
description: String,
moderators: [
{
type: Schema.Types.ObjectId,
ref: 'User'
}
]
}, {
timestamps: true
});
Forum.pre('remove', function(next) {
Post.find({"forumId": this._id})
.exec(function(err, posts) {
console.log("found posts " + posts);
for(var i = posts.length -1; i >= 0; i--) {
posts[i].remove();
}
});
Subscription.remove({"forumId": this._id}).exec();
next();
});
module.exports = mongoose.model('Forum', Forum);
//post.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = require('./user.js');
var Forum = require('./forum.js');
var Comment = require('./comment.js');
var Post = new Schema({
createdBy: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
postText: {
type: String,
required: true
},
forumId: {
type: Schema.Types.ObjectId,
ref: 'Forum'
},
}, {
timestamps: true
});
Post.pre('remove', function(next) {
Comment.remove({"postId": this._id}).exec();
next();
});
module.exports = mongoose.model('Post', Post);
//comment.js [SAME AS INCLUDED ABOVE]
But in this case, when remove is called on a forum instance, the Forum.pre('remove'... functionality causes an error to be thrown: TypeError: Post.find is not a function. The error is thrown at forum.js line 24 (second line in the Forum.pre(...) block)
The calling code is as follows:
forumRouter.route('/:forumId')
//delete forum by id: [ADMIN]
.delete(Verify.verifyOrdinaryUser, Verify.verifyAdmin, function(req, res, next) {
Forum.findById(req.params.forumId, function(err, forum) {
if(err) return next(err);
forum.remove();
res.json(forum);
});
});
While I have found instance of this error being thrown in my online research here and elsewhere, the causes there were incorrectly exported models or incorrectly defined schemas. The Post schema is being used successfully throughout the rest of my code with no issues, it is only this call to Post.find that is causing the error. And in fact, my postRouter code calls the following successfully:
postRouter.route('/')
// retrieve all forum posts: [ALL USERS]
.get(function(req, res, next) {
Post.find({})
.populate({
path: 'forumId',
model: 'Forum',
populate: {
path: 'moderators',
model: 'User'
}
})
.populate('createdBy')
.exec(function(err, posts){
if(err) return next(err);
res.json(posts);
});
});
I'm trying to create a REST api using express and mongoose. Below is the code for User model (user.server.model.js).
const mongoose = require('mongoose');
var userSchema = new mongoose.Schema({
name: {
first: { type: String, required: true },
last: { type: String, required: true }
},
loginId: { type: String, required: true, unique: true },
password: { type: String, required: true },
location: String,
meta: { age: Number, website: String },
isActive: Boolean,
createdOn: { type: Date, default: Date.now },
updatedOn: Date
});
var User = mongoose.model('User', userSchema);
exports.User = User;
I'm trying to use this User model in express route (routes.js) as below:
const express = require('express'),
User = require('../models/user.server.model'),
router = express.Router();
router.route('/users')
.post((req, res) => {
let user = new User({
name: req.body.name,
loginId: req.body.loginId,
password: req.body.password,
location: req.body.location,
meta: req.body.meta,
createdOn: req.body.createdOn,
updatedOn: req.body.updatedOn
});
user.save((err) => {
if (err) {
res.send(err);
}
else{
res.json({ message: 'User created' });
}
});
});
module.exports = router;
But when I try to test this api using Postman extension in Chrome I'm getting below error
TypeError: User is not a constructor
Node Version: 6.0
Can anyone please advise whats going wrong here.
You're using the require value directly as User, so you should change exports.User to module.exports in user.server.model.js:
module.exports = User;