Is it possible to query subdocuments directly using mongoose? - node.js

let's say there was a User model and a Post model. In this situation User's would have many posts; User would be the parent and Post would be the child. Is it possible to query for posts directly?
For instance if I wanted to do something like
app.get('/post/search/:query', (req,res) => {
Posts.find({title: req.params.query }, (err,post) => {
res.send(JSON.stringify(post))
})
})
or would one have to do:
app.get('/post/search/:query',(req,res) => {
let resultsFromQuery = [];
User.find({'post.title':req.params.query'}, (err,user) => {
user.posts.forEach((post) => {
if(post.title === req.params.query){
resultsFromQuery.push(post);
}
})
})
res.send(JSON.stringify(resultsFromQuery))
})
EDIT: Here is my schema's.
User Schema (Parent)
const mongoose = require('mongoose'),
Schema = mongoose.Schema,
PostSchema = require('./post.js');
let UserSchema = new Schema({
username: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
posts: [PostSchema]
})
module.exports = mongoose.model('User',UserSchema);
Post Schema (Child)
const mongoose = require('mongoose'),
Schema = mongoose.Schema;
let PostSchema = new Schema({
title: {
type: String
},
description: {
type: String
},
image: {
type: String
},
original_poster: {
id: {
type: String,
required: true
},
username: {
type: String,
required: true
}
},
tags: {
type: [String],
required: true
}
})
module.exports = PostSchema;
EDIT:
Here is a sample document
the result of db.users.find({username: 'john'})
{
"_id" : ObjectId("5a163317bf92864245250cf4"),
"username" : "john",
"password" : "$2a$10$mvE.UNgvBZgOURAv28xyA.UdlJi4Zj9IX.OIiOCdp/HC.Cpkuq.ru",
"posts" : [
{
"_id" : ObjectId("5a17c32d54d6ef4987ea275b"),
"title" : "Dogs are cool",
"description" : "I like huskies",
"image" : "https://media1.giphy.com/media/EvRj5lfd8ctUY/giphy.gif",
"original_poster" : {
"id" : "5a163317bf92864245250cf4",
"username" : "john"
},
"tags" : [
"puppies",
"dogs"
]
}
],
"__v" : 1
}

Yes you can find directly the post title from the user model. like bellow
User.find({"posts.title": "Cats are cool"}, (err, users) => {
if(err) {
// return error
}
return res.send(users)
})
That will return user with all post not only the matching post title. So to return only matching post title can use $ positional operator. like this query
User.find({"posts.title": "Cats are cool"},
{username: 1, "posts.$": 1}, // add that you need to project
(err, users) => {
if(err) {
// return error
}
return res.send(users)
})
that only return matching post

Since you are saving OP data, why not do:
// you'll need to adapt how your are getting the user-id here
const { user } = req
Post.find({ title: 'the title', 'original_poster.id': user.id }, (err, posts) => {
console.log(posts); })
Though I would advise you to adjust your Post-schema:
original_poster: {
type: Schema.Types.ObjectId,
ref: 'User'
}
},
Then you can do Post.find({}).populate('original_poster') to include it in your results.!

Related

Find if User Exist in array mongodb and Nodejs

I have this opportunity model that has this field likes, which is an array of users. How do I check first if the user exist already in that array and if they do I pull them and if they don't I push them back I am building a like creteria for posts
Here is my opportunity model
const mongoose = require("mongoose");
const OpportunityModel = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
content: {
type: String,
required: true,
trim: true,
},
likes: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
],
image: [
{
type: Object,
},
],
share_with_thoughts: {
type: mongoose.Schema.Types.ObjectId,
ref: "Shares",
},
comments: {
type: mongoose.Schema.Types.ObjectId,
ref: "Comment",
},
is_opportunity_applied: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
],
});
const Opportunity = mongoose.model("Opportunity", OpportunityModel);
module.exports = Opportunity;
What I tried doing but did not work
const likeOrUnlikeOpportunity = expressAsyncHandler(async (req, res) => {
let userId = req.user._id;
let opportunityId = req.params.opportunityId;
let isUserExist = await Opportunity.find({
$and: [{ _id: opportunityId }, { likes: { $elemMatch: { $eq: userId } } }],
}).populate("user", "user_id user_name");
if (isUserExist.length > 0) {
const unliked = await Opportunity.findByIdAndUpdate(
opportunityId,
{
$pull: { users: userId },
},
{ new: true }
).populate("user", "user_id user_name");
if (!unliked) {
res.status(500).send({ ErrMessaage: "an error occured" });
} else {
res.status(200).json(unliked);
}
} else {
const added = await Opportunity.findByIdAndUpdate(
opportunityId,
{
$push: { users: userId },
},
{ new: true }
).populate("user", "user_id user_name");
if (!added) {
res.status(500).send({ ErrMessaage: "an error occured" });
} else {
res.status(200).json(added);
}
}
});
In this case, the action should be dynamic [like | unlike] function, You don't have to chain the function since the like and unlike function/api can't be called at the same time.
Make Your Query Conditional;
Just make sure you have a way to identify between like and unlike.
const {like, postId} = req.body;
let query = {[`${'$' + (like ? 'push' : 'pull')}`]: {likes: userId}};
//assumes that you have the post id
// you can decide not to wait for it to update, just to be sure it did update
await post.findByIdAndUpdate(postId, query).exec()
I hope this helps.

How to Delete Comment from Post on Node, express and Mongoose and Ajax

Please i need help on how to delete a single comment from a Post. when i click delete it return 500 error. some of the things that are confusing me here is, if i pass both post and comment ids on the link, how will i tell Ajax that this one is for post and this one is for comment.
Here is my posts schema
const postSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
from: {
type: String,
required: true
},
createdAt: {
required: true,
default: Date.now
},
postImage: {
type: String,
require: true
},
comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }]
})
here is my ajax from main.js file.
/deleting comment with Ajax
$(document).ready(function() {
$('.delete-comment').on('click', function(e) {
const $target = $(e.target);
const id = $target.attr('data-id');
$.ajax({
type: 'DELETE',
url: '/posts/comments/'+id,
success: function(response) {
window.location.href='/posts';
},
error: function(err){
console.log(err);
}
});
});
});
my routes/comments
//Delete comment inside a post
router.delete( '/comments/:id', function( req, res ){
const post = Post.findOne({_id: req.params.postId});
const ObjectId = mongoose.Types.ObjectId;
let query = {_id:new ObjectId(req.params.id)}
console.log(query)
post.comments.delete(query, function(err) {
if(err){
console.log(err);
}
res.send('Success');
});
})
my views/index.ejs
//Comments and link
<% const counter = post.comments.length >= 2 ? "Comments" : "Comment"; %>
<button class="show-comments"><%= post.comments.length + " " + counter + "" %></button>
<% %>
<div class="postcomments" ><% post.comments.forEach(item => { %>
<ul >
<li><%= item.description %></li>
<a class="delete-comment" href="#" data-id="<%=item._id%>">Delete</a>
</ul>
<% });%>
my app.js
//use route from app.js
var commentRouter = require('./routes/comments');
app.use('/posts', commentRouter);
here is what is being returned on my terminal
DELETE /posts/comments/5e8ad7121277855e656b3379 500 5.395 ms - 3698
You need to know both the postId and the commentId to be able to delete the comment from posts collection. Also it would be good to delete the comment inside the comments collection.
So change your delete route to include postId and commentId as req.params.
You can delete a comment from posts using the findByIdAndUpdate method and $pull operator.
router.delete("/comments/:postId/:commentId", async function (req, res) {
try {
const post = await Post.findByIdAndUpdate(
req.params.postId,
{
$pull: { comments: req.params.commentId },
},
{ new: true }
);
if (!post) {
return res.status(400).send("Post not found");
}
await Comment.findByIdAndDelete(req.params.commentId);
res.send("Success");
} catch (err) {
console.log(err);
res.status(500).send("Something went wrong");
}
});
TEST
Let's say we have this post document with 3 comments.
Posts:
{
"_id" : ObjectId("5e8b10c49ae619486094ed10"),
"comments" : [
ObjectId("5e8b104f9ae619486094ed0d"),
ObjectId("5e8b10599ae619486094ed0e"),
ObjectId("5e8b105e9ae619486094ed0f")
],
"title" : "Title",
"description" : "Description...",
"from" : "From",
"postImage" : "Post Image",
"createdAt" : ISODate("2020-04-06T14:21:40.884+03:00")
}
Comments:
{
"_id" : ObjectId("5e8b105e9ae619486094ed0f"),
"message" : "Comment 3"
},
{
"_id" : ObjectId("5e8b10599ae619486094ed0e"),
"message" : "Comment 2"
},
{
"_id" : ObjectId("5e8b104f9ae619486094ed0d"),
"message" : "Comment 1"
}
If we want to delete the comment with _id:5e8b10599ae619486094ed0e, we need to send a DELETE request to our route using url like this:
http://localhost:3000/posts/comments/5e8b10c49ae619486094ed10/5e8b10599ae619486094ed0e
5e8b10c49ae619486094ed10 is the postId, 5e8b10599ae619486094ed0e is the commentId.
Result will be like this:
Posts:
{
"_id" : ObjectId("5e8b10c49ae619486094ed10"),
"comments" : [
ObjectId("5e8b104f9ae619486094ed0d"),
ObjectId("5e8b105e9ae619486094ed0f")
],
"title" : "Title",
"description" : "Description...",
"from" : "From",
"postImage" : "Post Image",
"createdAt" : ISODate("2020-04-06T14:21:40.884+03:00")
}
Comments:
{
"_id" : ObjectId("5e8b105e9ae619486094ed0f"),
"message" : "Comment 3"
},
{
"_id" : ObjectId("5e8b104f9ae619486094ed0d"),
"message" : "Comment 1"
}
Your nodejs/express route contains this code. Maybe it should do more with possible errors: specifically, pass the error to the next() function that's the third parameter of any route handler.
post.comments.delete(query, function(err) {
if(err){
console.log(err)
return next(err)
}
res.send('Success')
});
Passing an error value to next() should deliver the error message to the user. And, you have the same message showing up on your server's console.log. So if the error is from there you should learn more about it.
I am facing the same problem Except that before erasing the post, I want to make sure that the user deleting the post is the creator of the same post. My data set is a little bit different.
import mongoose from 'mongoose'
const postSchema = mongoose.Schema(
{
title: {
type: String,
required: true,
},
comment: { type: String, required: true },
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'User',
},
imagePost: { type: String, required: true },
},
{
timestamps: true,
}
)
const stationSchema = mongoose.Schema(
{
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'User',
},
nameUnit: {
type: String,
required: true,
},
typeOfPoint: { type: String },
image: {
type: String,
required: true,
},
lat: {
type: Number,
required: true,
},
long: {
type: Number,
required: true,
},
// Base
nameBase: { type: String, required: true },
element: {
type: String,
required: true,
},
baseCommanderInfo: { type: String },
aboutBaseInfo: { type: String },
// Unit
unitSuperviserInfo: { type: String },
unitCommanderInfo: { type: String },
unitInfo: { type: String },
taskInfo: { type: String },
benefitInfo: { type: String },
// address
country: { type: String },
province: { type: String },
town: { type: String },
adresse: { type: String },
postalCode: { type: String },
posts: [postSchema],
},
{
timestamps: true,
}
)
const Station = mongoose.model('Station', stationSchema)
export default Station
NodeControler
const removeStationPost = asyncHandler(async (req, res) => {
const stationId = req.params.id
const postId = req.params.idPost
const userId = req.user._id
console.log(stationId)
console.log(postId)
console.log(userId)
const station = await Station.findById(stationId)
if (station) {
station.posts.pull(postId)
await station.save()
res.status(201).json({ message: 'Post removed' })
} else {
res.status(404)
throw new Error('Post not found')
}
})
So now everybody can delete anybody else post with Postman

How can i send a query to Push details to my MongoDB using Node and mongoose [duplicate]

Basically I have a mongodb collection called 'people'
whose schema is as follows:
people: {
name: String,
friends: [{firstName: String, lastName: String}]
}
Now, I have a very basic express application that connects to the database and successfully creates 'people' with an empty friends array.
In a secondary place in the application, a form is in place to add friends. The form takes in firstName and lastName and then POSTs with the name field also for reference to the proper people object.
What I'm having a hard time doing is creating a new friend object and then "pushing" it into the friends array.
I know that when I do this via the mongo console I use the update function with $push as my second argument after the lookup criteria, but I can't seem to find the appropriate way to get mongoose to do this.
db.people.update({name: "John"}, {$push: {friends: {firstName: "Harry", lastName: "Potter"}}});
Assuming, var friend = { firstName: 'Harry', lastName: 'Potter' };
There are two options you have:
Update the model in-memory, and save (plain javascript array.push):
person.friends.push(friend);
person.save(done);
or
PersonModel.update(
{ _id: person._id },
{ $push: { friends: friend } },
done
);
I always try and go for the first option when possible, because it'll respect more of the benefits that mongoose gives you (hooks, validation, etc.).
However, if you are doing lots of concurrent writes, you will hit race conditions where you'll end up with nasty version errors to stop you from replacing the entire model each time and losing the previous friend you added. So only go to the latter when it's absolutely necessary.
The $push operator appends a specified value to an array.
{ $push: { <field1>: <value1>, ... } }
$push adds the array field with the value as its element.
Above answer fulfils all the requirements, but I got it working by doing the following
var objFriends = { fname:"fname",lname:"lname",surname:"surname" };
People.findOneAndUpdate(
{ _id: req.body.id },
{ $push: { friends: objFriends } },
function (error, success) {
if (error) {
console.log(error);
} else {
console.log(success);
}
});
)
Another way to push items into array using Mongoose is- $addToSet, if you want only unique items to be pushed into array. $push operator simply adds the object to array whether or not the object is already present, while $addToSet does that only if the object is not present in the array so as not to incorporate duplicacy.
PersonModel.update(
{ _id: person._id },
{ $addToSet: { friends: friend } }
);
This will look for the object you are adding to array. If found, does nothing. If not, adds it to the array.
References:
$addToSet
MongooseArray.prototype.addToSet()
Use $push to update document and insert new value inside an array.
find:
db.getCollection('noti').find({})
result for find:
{
"_id" : ObjectId("5bc061f05a4c0511a9252e88"),
"count" : 1.0,
"color" : "green",
"icon" : "circle",
"graph" : [
{
"date" : ISODate("2018-10-24T08:55:13.331Z"),
"count" : 2.0
}
],
"name" : "online visitor",
"read" : false,
"date" : ISODate("2018-10-12T08:57:20.853Z"),
"__v" : 0.0
}
update:
db.getCollection('noti').findOneAndUpdate(
{ _id: ObjectId("5bc061f05a4c0511a9252e88") },
{ $push: {
graph: {
"date" : ISODate("2018-10-24T08:55:13.331Z"),
"count" : 3.0
}
}
})
result for update:
{
"_id" : ObjectId("5bc061f05a4c0511a9252e88"),
"count" : 1.0,
"color" : "green",
"icon" : "circle",
"graph" : [
{
"date" : ISODate("2018-10-24T08:55:13.331Z"),
"count" : 2.0
},
{
"date" : ISODate("2018-10-24T08:55:13.331Z"),
"count" : 3.0
}
],
"name" : "online visitor",
"read" : false,
"date" : ISODate("2018-10-12T08:57:20.853Z"),
"__v" : 0.0
}
First I tried this code
const peopleSchema = new mongoose.Schema({
name: String,
friends: [
{
firstName: String,
lastName: String,
},
],
});
const People = mongoose.model("person", peopleSchema);
const first = new Note({
name: "Yash Salvi",
notes: [
{
firstName: "Johnny",
lastName: "Johnson",
},
],
});
first.save();
const friendNew = {
firstName: "Alice",
lastName: "Parker",
};
People.findOneAndUpdate(
{ name: "Yash Salvi" },
{ $push: { friends: friendNew } },
function (error, success) {
if (error) {
console.log(error);
} else {
console.log(success);
}
}
);
But I noticed that only first friend (i.e. Johhny Johnson) gets saved and the objective to push array element in existing array of "friends" doesn't seem to work as when I run the code , in database in only shows "First friend" and "friends" array has only one element !
So the simple solution is written below
const peopleSchema = new mongoose.Schema({
name: String,
friends: [
{
firstName: String,
lastName: String,
},
],
});
const People = mongoose.model("person", peopleSchema);
const first = new Note({
name: "Yash Salvi",
notes: [
{
firstName: "Johnny",
lastName: "Johnson",
},
],
});
first.save();
const friendNew = {
firstName: "Alice",
lastName: "Parker",
};
People.findOneAndUpdate(
{ name: "Yash Salvi" },
{ $push: { friends: friendNew } },
{ upsert: true }
);
Adding "{ upsert: true }" solved problem in my case and once code is saved and I run it , I see that "friends" array now has 2 elements !
The upsert = true option creates the object if it doesn't exist. default is set to false.
if it doesn't work use below snippet
People.findOneAndUpdate(
{ name: "Yash Salvi" },
{ $push: { friends: friendNew } },
).exec();
An easy way to do that is to use the following:
var John = people.findOne({name: "John"});
John.friends.push({firstName: "Harry", lastName: "Potter"});
John.save();
In my case, I did this
const eventId = event.id;
User.findByIdAndUpdate(id, { $push: { createdEvents: eventId } }).exec();
Push to nested field - use a dot notation
For anyone wondering how to push to a nested field when you have for example this Schema.
const UserModel = new mongoose.schema({
friends: {
bestFriends: [{ firstName: String, lastName: String }],
otherFriends: [{ firstName: String, lastName: String }]
}
});
You just use a dot notation, like this:
const updatedUser = await UserModel.update({_id: args._id}, {
$push: {
"friends.bestFriends": {firstName: "Ima", lastName: "Weiner"}
}
});
This is how you could push an item - official docs
const schema = Schema({ nums: [Number] });
const Model = mongoose.model('Test', schema);
const doc = await Model.create({ nums: [3, 4] });
doc.nums.push(5); // Add 5 to the end of the array
await doc.save();
// You can also pass an object with `$each` as the
// first parameter to use MongoDB's `$position`
doc.nums.push({
$each: [1, 2],
$position: 0
});
doc.nums;
// This is the my solution for this question.
// I want to add new object in worKingHours(array of objects) -->
workingHours: [
{
workingDate: Date,
entryTime: Date,
exitTime: Date,
},
],
// employeeRoutes.js
const express = require("express");
const router = express.Router();
const EmployeeController = require("../controllers/employeeController");
router
.route("/:id")
.put(EmployeeController.updateWorkingDay)
// employeeModel.js
const mongoose = require("mongoose");
const validator = require("validator");
const employeeSchema = new mongoose.Schema(
{
name: {
type: String,
required: [true, "Please enter your name"],
},
address: {
type: String,
required: [true, "Please enter your name"],
},
email: {
type: String,
unique: true,
lowercase: true,
required: [true, "Please enter your name"],
validate: [validator.isEmail, "Please provide a valid email"],
},
phone: {
type: String,
required: [true, "Please enter your name"],
},
joiningDate: {
type: Date,
required: [true, "Please Enter your joining date"],
},
workingHours: [
{
workingDate: Date,
entryTime: Date,
exitTime: Date,
},
],
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
);
const Employee = mongoose.model("Employee", employeeSchema);
module.exports = Employee;
// employeeContoller.js
/////////////////////////// SOLUTION IS BELOW ///////////////////////////////
// This is for adding another day, entry and exit time
exports.updateWorkingDay = async (req, res) => {
const doc = await Employee.findByIdAndUpdate(req.params.id, {
$push: {
workingHours: req.body,
},
});
res.status(200).json({
status: "true",
data: { doc },
});
};
https://www.youtube.com/watch?v=gtUPPO8Re98
I ran into this issue as well. My fix was to create a child schema. See below for an example for your models.
---- Person model
const mongoose = require('mongoose');
const SingleFriend = require('./SingleFriend');
const Schema = mongoose.Schema;
const productSchema = new Schema({
friends : [SingleFriend.schema]
});
module.exports = mongoose.model('Person', personSchema);
***Important: SingleFriend.schema -> make sure to use lowercase for schema
--- Child schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const SingleFriendSchema = new Schema({
Name: String
});
module.exports = mongoose.model('SingleFriend', SingleFriendSchema);

Accessing a schema inside a schema using Express Router and MongoDG

I'm trying to create a route where it takes in a parameter for a username and then displays that users information. Only thing is, the username is in the user schema from when the user signs up. The profile schema references the user schema. How do I use the username parameter in the findOne call to display the users profile data?
User schema:
const UserSchema = new Schema({
username: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
module.exports = User = mongoose.model("users", UserSchema);
Profile schema:
const ProfileSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: "users"
},
name: {
type: String
},
image: {
type: String
},
bio: {
type: String
},
location: {
type: String
},
website: {
type: String
},
social: {
youtube: {
type: String
},
facebook: {
type: String
},
instagram: {
type: String
},
twitter: {
type: String
}
}
});
module.exports = User = mongoose.model("profile", ProfileSchema);
Route:
router.get("/user/:username", (req, res) => {
const errors = {};
Profile.findOne({ user: req.params.user.username })
.populate("user", "username")
.then(profile => {
if (!profile) {
errors.noprofile = "There is no profile for this user";
return res.status(404).json(errors);
}
res.json(profile);
})
.catch(err => res.status(404).json(err));
});
Please try this :
router.get("/user/:username", async (req, res) => {
const errors = {};
try {
const profile = await User.aggregate([
{ $match: { username: req.params.username } },
{ $lookup: { from: "profile", localField: "_id", foreignField: "user", as: "userProfile" } },
{ $project: { userProfile: { $arrayElemAt: ["$userProfile", 0] }, username: 1, _id:0 } }
]).exec();
if (!profile.length) {
errors.noprofile = "There is no profile for this user";
return res.status(404).json(errors);
}
res.json(profile[0]);
} catch (error) {
console.log('Error in retrieving user from DB ::', error);
return res.status(404);
}
})
Try using aggregate, firstly you check-in user table for getting details of a specific username then fetch the profile details as below using lookup, if no profile found after unwind the document will not be fetched and you can check on aggregate result's length as aggregate always return an array in result :
User.aggregate([
{$match:{ username: req.params.user.username }},
{$lookup:{from:"profile",localField:"_id",foreignField:"userId",as:"profileData"}},
{$unwind:"$profileData"},
{$project:{profileData:1,username:1}}
{$limit:1}
])
.then(profile => {
if (!profile.length) {
errors.noprofile = "There is no profile for this user";
return res.status(404).json(errors);
}
res.json(profile[0]);
})
You can do it in 2 steps.
Look for users containing username in userSchema, get it's id.
Then in promise, use that id to, look for profileSchema contains.
router.get("/user/:username", (req, res) => {
users.findOne({ username: req.params.username }).then(_user=>{
profile.findOne({ user: _user._id }).populate('user').then(_profile => {
res.json(_profile);
})
})
});
This code will look for username in userSchema and look for userSchema's id in profileSchema then returns profileSchema populated with user.

Issue with displaying data using mongodb

I have a web app where users can post items and it returns it in a table format. But I am wanting to create a section where a user can view their individual submissions. I have the first part working correctly. And it does show a list of user items. However when I am trying to only view that one persons submissions no data shows. When I console.log it I am getting my user data but I am not getting the item data. The item data just returns an empty array. I am not sure what all I need to post on here but I am going to show both Schemas and the route for listing the data.
UserSchema:
const UserSchema = new mongoose.Schema({
username: {
type: String,
trim: true,
unique: true,
required: true,
minlength: 3,
maxlength: 15
},
firstName: {
type: String,
required: true,
minlength: 3,
maxlength: 15
},
lastName: {
type: String,
required: true,
minlength: 3,
maxlength: 15
},
email: {
type: String,
unique: true,
required: true
},
items: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Items"
}
],
isAdmin: {
type: Boolean,
default: false
}
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSchema);
ItemSchema:
const ItemSchema = new mongoose.Schema({
name: {
type: String,
required: true,
minlength: 3,
maxlength: 20
},
description: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
image: String,
noImage: String,
createdAt: {
type: Date,
default: Date.now
},
createdBy: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
}
});
module.exports = mongoose.model("Items", ItemSchema);
Route:
router.get("/:id", middleware.isLoggedIn, function(req, res) {
User.findById(req.params.id, function(err, foundUser) {
if (err || !foundUser) {
req.flash("error", "Something went wrong");
res.render("index");
} else {
Item.find()
.where("creadtedBy.id")
.equals(foundUser._id)
.exec(function(err, items) {
if (err || !foundUser) {
req.flash("error", "Something went wrong");
res.render("index");
}
console.log("user" + foundUser);
console.log("items" + items);
res.render("inventory", {
user: foundUser,
items: items
});
});
}
});
});
So, what am I doing wrong here? ... Thanks
Here is the route that joins the user to the item:
router.post("/item/add", middleware.isLoggedIn, (req, res) => {
User.findById(req.user._id, (err, user) => {
upload(req, res, err => {
if (err) {
req.flash("error", "error uploading image");
return res.redirect("back");
}
var name = req.body.name;
if (typeof req.file !== "undefined") {
var image = "/uploads/" + req.file.filename;
} else {
image = "/uploads/no-img.PNG";
}
var description = req.body.description;
var price = req.body.price;
var createdBy = { id: req.user._id, username: req.user.username };
var newItem = {
name: name,
image: image,
description: description,
price: price,
createdBy: createdBy
};
Item.create(newItem, (err, newlyCreated) => {
if (err) {
return console.log(err);
} else {
user.items.push(newlyCreated);
user.save();
res.redirect("/products");
}
});
});
});
});
And here is my user info from mongo:
{
"_id" : ObjectId("5aea79207c1f272d186ab97a"),
"items" : [
ObjectId("5aea793b7c1f272d186ab97b")
],
"isAdmin" : true,
"username" : "testuser",
"firstName" : "Test",
"lastName" : "User",
"email" : "test#user.com",
"__v" : 1
}
And here is the Item data from mongo:
{
"_id" : ObjectId("5aea793b7c1f272d186ab97b"),
"createdBy" : {
"id" : ObjectId("5aea79207c1f272d186ab97a"),
"username" : "testuser"
},
"name" : "Test",
"image" : "/uploads/no-img.PNG",
"description" : "Item",
"price" : 1,
"createdAt" : ISODate("2018-05-03T02:51:39.818Z"),
"__v" : 0
}

Resources