I am using MongoDB + Node.js to create an app, but I am receiving an error for this code:
company.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var companySchema = Schema({
creator: {
type: Schema.Types.ObjectId,
ref: 'User'
},
name: String,
description: String,
categories: [String],
website: String,
address: String,
statuses: [{
date: { type: Date, default: Date.now },
status: String
}],
friends: [{
name: String,
description: String
}],
priority: Number,
isActive: Boolean,
contacts: [{
type: Schema.Types.ObjectId,
ref: 'ContactPerson'
}],
createdOn: { type: Date, default: Date.now }
});
module.exports = mongoose.model('Company', companySchema);
api.js
api.route('/company')
.post(function(req, res) {
var company = new Company({
creator: req.decoded.id,
name: req.body.name,
description: req.body.description,
categories: req.body.categories,
website: req.body.website,
address: req.body.address,
friends.name: req.body.friendName,
statuses: { status: "New Company" },
priority: req.body.priority,
});
company.save(function(err, newCompany) {
if(err) {
res.send(err);
return
}
res.json({ message: "New company has been created!" });
});
})
Error
friends.name: req.body.friendName,
SyntaxError: Unexpected token .
I also tried with friend['name'] but the result was the same: SyntaxError: Unexpected token [
Please tell me where is my mistake
Try:
var company = new Company({
creator: req.decoded.id,
name: req.body.name,
description: req.body.description,
categories: req.body.categories,
website: req.body.website,
address: req.body.address,
friends: {
name: req.body.friendName
},
statuses: { status: "New Company" },
priority: req.body.priority,
});
or:
var company = new Company({
creator: req.decoded.id,
name: req.body.name,
description: req.body.description,
categories: req.body.categories,
website: req.body.website,
address: req.body.address,
'friends.name': req.body.friendName,
statuses: { status: "New Company" },
priority: req.body.priority,
});
depend on what you're after.
Use latest version of nvm and then run it
Write nvm use version 16.
And then write: npx nodemon index.
Related
hi I'm using React with mongoDB I'm new to the mongoDB. I guess My schemas is having problems
how do I get posts that I'm following users. I've been facing this problem for a week
I can get All the posts of my following users, I think it might be unnecessary I'd like to just get lastest 10 posts of my following users
if there is a tip to get posts please let me know thanks for reading this question
Here's my Post Schema
import mongoose from "mongoose";
const postSchema = mongoose.Schema({
title: String,
message: String,
name: String,
tags: [String],
picture: String,
likes: {
type: [String],
default: [],
},
createdAt: {
type: Date,
default: new Date(),
},
profilePicture: String,
userId: String,
comments: {
type: [
{
commentUserId: String,
commentUserName: String,
comment: String,
createdAt: Date,
},
],
},
});
const Post = mongoose.model("Post", postSchema);
export default Post;
Here's User Schema
import mongoose from "mongoose";
import bcrypt from "bcrypt";
const userSchema = mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
id: { type: String },
profilePicture: {
type: String,
default:
"https://icon-library.com/images/anonymous-avatar-icon/anonymous-avatar-icon-25.jpg",
},
isAdmin: {
type: Boolean,
required: true,
default: false,
},
userPosts: [
{
_id: String,
title: String,
picture: String,
message: String,
tags: [String],
name: String,
profilePicture: String,
userId: String,
likes: [String],
comments: [
{
commentUserId: String,
commentUserName: String,
comment: String,
createdAt: Date,
},
],
},
],
following: {
type: [String],
default: [],
},
followers: {
type: [String],
default: [],
},
notifications: [
{
_id: mongoose.Schema.Types.ObjectId,
sender: String,
notificationType: String,
read: Boolean,
},
],
});
const User = mongoose.model("User", userSchema);
export default User;
I'm trying to populate my user requests.profileId but it returns only nulls.
I have the following schemas:
First Schema:
const profileSchema = new mongoose.Schema({
_id: { type: Number }, //<- _id is defined as a number which represents mobile number (easier for me to handle)
first: { type: String },
second: { type: String },
});
module.exports = mongoose.model('Profile', profileSchema, 'profiles');
Second Schema:
const userSchema = new mongoose.Schema({
firstName: { type: String },
lastName: { type: String },
requests: [
{
profileId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Profile',
},
requestTime: { type: Date, default: Date.now },
},
],
});
module.exports = mongoose.model('User', userSchema, 'users');
Here is my code:
const user = await User.findById(req.user).populate('requests.profileId');
console.log(user.requests);
Here is the output:
[
{
_id: 6201633869648e2b74c00a10,
profileId: null,
requestTime: 2022-02-07T18:21:44.722Z
},
{
_id: 6201633b69648e2b74c00a11,
profileId: null,
requestTime: 2022-02-07T18:21:47.238Z
},
{
_id: 620238f9d2b5dd3dee6c41a2,
profileId: null,
requestTime: 2022-02-08T09:33:45.176Z
},
{
_id: 620239253220343dfd7cfdd9,
profileId: null,
requestTime: 2022-02-08T09:34:29.780Z
}
]
Here is the output without populate:
[
{
_id: 6201633869648e2b74c00a10,
profileId: 393732353235303134343330, //<- typeof profileId is obeject
requestTime: 2022-02-07T18:21:44.722Z
},
{
_id: 6201633b69648e2b74c00a11,
profileId: 393732353435353333313131,
requestTime: 2022-02-07T18:21:47.238Z
},
{
_id: 620238f9d2b5dd3dee6c41a2,
profileId: 393732353435353333313131,
requestTime: 2022-02-08T09:33:45.176Z
},
{
_id: 620239253220343dfd7cfdd9,
profileId: 393732353435353333313131,
requestTime: 2022-02-08T09:34:29.780Z
}
]
Currently Profile.findById(mobileNumber) works fine.
Any ideas what went wrong?
Will greatly appreciate your assistance.
Thanks in advance :)
Try this might work let me know if it doesn't
const user = await User.findById(req.user).populate('Profile');
console.log(user.requests);
try this:
User.findById(req.user).populate({
path: 'requests',
populate: {
path: 'profileId',
model: 'Profile'
}
})
For future readers having the same issue!
I've found a solution for this issue.
I had to change the profileId type to Number in my userSchema:
const userSchema = new mongoose.Schema({
firstName: { type: String },
lastName: { type: String },
requests: [
{
profileId: {
type: Number // and NOT use type: mongoose.Schema.Types.ObjectId,
ref: 'Profile',
},
requestTime: { type: Date, default: Date.now },
},
],
});
module.exports = mongoose.model('User', userSchema, 'users');
Now it works!
i did find a post by id and i did console log output and it was that:
{ comments: [ 5c263bf01b764a11c479f69c, 5c263c41133ace1655edee76 ],
_id: 5c263bc61b764a11c479f69b,
title: 'good laptop',
category: 'Laptop',
brand: 'dell',
Condition: 'Good Condition',
image: 'https://avisassets.abgemea.com/.imaging/flexibleIntroLarge/dms/DMS/local/ZA/fleet/fleet-page/luxury-cars-feature.jpg',
price: 2000,
priceState: 'Negociable',
city: 'Algiers',
phone: '71717171555',
email: 'test#test.com',
description: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
date: '28/11/2018',
userId: 5c25344c321f0d5a777ace00,
__v: 2 }
i did read mongoose documentation about populate but i didn't figure out how to populate the userIdand also populate comments and the nested userId under the comments
Assuming userId is a field in your Posts schema, you can do it this way:
Posts.findOne({ id: 'your-post-id' })
.populate('userId')
.populate({ path: 'comments',
populate: { path: 'userId',
model:'User' }
})
.exec(callback);
Your schemas should be similar to this:
var postsSchema = new Schema({
comments: { type: [Schema.ObjectId], ref: 'Comment' },
userId: { type: Schema.ObjectId, ref: 'User' },
...
});
var commentsSchema = new Schema({
userId: { type: Schema.ObjectId, ref: 'User' },
...
});
I am writing a small application that uses javascript, node, mongoDB, and mongoose. I have two collections; users and groups where every group contains an array of users
User:{_id:{type: String, required: true} FirstName: {type: String, required: true}, ..}
Group{_id:{type: String, required: true}, users:[{user: userSchema}] }
I am writing an api unit test using Mocha and Superagent. When I insert a sample document for the group that includes a nested objects for the users, I got a validation error?
Could you please let me know what is going wrong with this example?
var userSchema =
{
_id: {
type: String,
required: true,
},
profile: {
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
}
};
var GroupSchema =
{
_id: {
type: String,
required: true
},
users:[{
user: User.userSchema
}]
};
it('can query group by id', function(done) {
var users = [
{ _id: 'az', profile: {firstName: 'a', lastName: 'z'}},
{ _id: 'bz', profile: {firstName: 'b', lastName: 'z'}},
];
User.create(users, function(error, users) {
assert.ifError(error);
Group.create({ _id: 'ab', users: [{ _id: 'az', profile: {firstName: 'a', lastName: 'z'}}, { _id: 'bz', profile: {firstName: 'b', lastName: 'z'}}] }, function(error, doc) {
assert.ifError(error);
var url = URL_ROOT + '/api/groups/id/ab';
superagent.get(url, function(error, res) {
assert.ifError(error);
var result;
assert.doesNotThrow(function() {
result = JSON.parse(res.text);
});
assert.ok(result.group);
assert.equal(result.group._id, 'ab');
done();
});
});
});
});
Error Message:
Uncaught ValidationError: ChatGroup validation failed: users.1._id: Cast to ObjectID failed for value "bz" at path "_id", users.0._id: Cast to ObjectID failed for value "az" at path "_id", users.0.user.profile.lastName: Path `user.profile.lastName` is required., users.0.user.profile.firstName: Path `user.profile.firstName` is required., users.0.user._id: Path `user._id` is required., users.1.user.profile.lastName: Path `user.profile.lastName` is required., users.1.user.profile.firstName: Path `user.profile.firstName` is
I think your GroupSchema definition is incorrect:
var GroupSchema =
{
_id: {
type: String,
required: true
},
users:[{
user: User.userSchema
}]
};
The way you're using it in the test users array should have type of User.userSchema array:
var GroupSchema =
{
_id: {
type: String,
required: true
},
users:[{
type: User.userSchema // type, not 'user'
}]
// OR just: users: [User.userSchema]
};
Otherwise, if you still need to use your original schema, then in your test you should use it this way:
var users = [
{ user: { _id: 'az', profile: {firstName: 'a', lastName: 'z'}} },
{ user: { _id: 'bz', profile: {firstName: 'b', lastName: 'z'}} },
];
I am trying to populate() all the subscriptions in my User model with data from the Show model. I have tried .populate('subscriptions.show') but it does nothing to the results.
If I make subscriptions a plain array of Refs like so
subscriptions: [{type: Schema.Types.ObjectId, ref: 'Show'}]
doing a populate('subscriptions') works as intended
I have looked at every similar question I could find on Stackoverflow and what I could find on the docs. I can't see what I am doing wrong.
complete test file source that i am working with https://gist.github.com/anonymous/b7b6d6752aabdd1f9b59
Schema and Models
var userSchema = new Schema({
email: String,
displayName: String,
subscriptions: [{
show: {type: Schema.Types.ObjectId, ref: 'Show'},
favorite: {type: Boolean, default: false}
}]
});
var showSchema = new Schema({
title: String,
overview: String,
subscribers: [{type: Schema.Types.ObjectId, ref: 'User'}],
episodes: [{
title: String,
firstAired: Date
}]
});
var User = mongoose.model('User', userSchema);
var Show = mongoose.model('Show', showSchema);
Initial Data
var user = new User({
email: "test#test.com",
displayName: "bill"
});
user.save(function(err, user) {
var show = new Show({
title: "Some Show",
overview: "A show about some stuff."
});
show.save();
user.subscriptions.push(show);
user.save();
});
The Query
User.findOne({
displayName: 'bill'
})
.populate('subscriptions.show')
.exec(function(err, user) {
if (err) {
console.log(err);
}
console.log(user);
});
results in:
{
_id: 53a7a39d878a965c4de0b7f2,
email: 'test#test.com',
displayName: 'bill',
__v: 1,
subscriptions: [{
_id: 53a7a39d878a965c4de0b7f3,
favorite: false
}]
}
Some code perhaps, also some corrections to your approach. You kind of want a "manyToMany" type of join which you can make as follows:
var async = require("async"),
mongoose = require("mongoose"),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/user');
var userSchema = new Schema({
email: String,
displayName: String,
subscriptions: [{ type: Schema.Types.ObjectId, ref: 'UserShow' }]
});
userShows = new Schema({
show: { type: Schema.Types.ObjectId, Ref: 'Show' },
favorite: { type: Boolean, default: false }
});
var showSchema = new Schema({
title: String,
overview: String,
subscribers: [{ type: Schema.Types.ObjectId, ref: 'User' }],
episodes: [{
title: String,
firstAired: Date
}]
});
var User = mongoose.model('User', userSchema);
var Show = mongoose.model('Show', showSchema);
var UserShow = mongoose.model('UserShow', userShows);
var user = new User({
email: 'test#test.com',
displayName: 'bill'
});
user.save(function(err,user) {
var show = new Show({
title: "Some Show",
overview: "A show about some stuff."
});
show.subscribers.push( user._id );
show.save(function(err,show) {
var userShow = new UserShow({ show: show._id });
user.subscriptions.push( userShow._id );
userShow.save(function(err,userShow) {
user.save(function(err,user) {
console.log( "done" );
User.findOne({ displayName: "bill" })
.populate("subscriptions").exec(function(err,user) {
async.forEach(user.subscriptions,function(subscription,callback) {
Show.populate(
subscription,
{ path: "show" },
function(err,output) {
if (err) throw err;
callback();
});
},function(err) {
console.log( JSON.stringify( user, undefined, 4) );
});
});
});
});
});
});
That should show a populated response much like this:
{
"_id": "53a7b8e60462281231f2aa18",
"email": "test#test.com",
"displayName": "bill",
"__v": 1,
"subscriptions": [
{
"_id": "53a7b8e60462281231f2aa1a",
"show": {
"_id": "53a7b8e60462281231f2aa19",
"title": "Some Show",
"overview": "A show about some stuff.",
"__v": 0,
"episodes": [],
"subscribers": [
"53a7b8e60462281231f2aa18"
]
},
"__v": 0,
"favorite": false
}
]
}
Or without the "manyToMany" works also. Note here that there is no initial call to populate:
var async = require("async"),
mongoose = require("mongoose"),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/user');
var userSchema = new Schema({
email: String,
displayName: String,
subscriptions: [{
show: {type: Schema.Types.ObjectId, ref: 'UserShow' },
favorite: { type: Boolean, default: false }
}]
});
var showSchema = new Schema({
title: String,
overview: String,
subscribers: [{ type: Schema.Types.ObjectId, ref: 'User' }],
episodes: [{
title: String,
firstAired: Date
}]
});
var User = mongoose.model('User', userSchema);
var Show = mongoose.model('Show', showSchema);
var user = new User({
email: 'test#test.com',
displayName: 'bill'
});
user.save(function(err,user) {
var show = new Show({
title: "Some Show",
overview: "A show about some stuff."
});
show.subscribers.push( user._id );
show.save(function(err,show) {
user.subscriptions.push({ show: show._id });
user.save(function(err,user) {
console.log( "done" );
User.findOne({ displayName: "bill" }).exec(function(err,user) {
async.forEach(user.subscriptions,function(subscription,callback) {
Show.populate(
subscription,
{ path: "show" },
function(err,output) {
if (err) throw err;
callback();
});
},function(err) {
console.log( JSON.stringify( user, undefined, 4) );
});
});
});
});
});
check answer: https://stackoverflow.com/a/28180427/3327857
Car .find() .populate({
path: 'partIds',
model: 'Part',
populate: {
path: 'otherIds',
model: 'Other'
}
})