How to populate using mongoose? I have a problem - javascript

I'm making a simple example of CRUD for a larger and open source project. Right now I want to populate with user data, I have already looked at the documentation and some forums and I am not able to solve the problem that is causing here.
The message in terminal "Populated User undefined"
Could anyone help?
userModel
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
name: {
type: String
},
});
userController
var mongoose = require('mongoose'),
User = mongoose.model('Users');
exports.create_a_user = function(req, res) {
var new_user = new User(req.body);
new_user.save(function(err, user) {
if (err)
res.send(err);
res.json(user);
});
};
msgModel
module.exports = mongoose.model('Users', userSchema);
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var msgSchema = new Schema({
title: {
type: String
},
body: {
type: String
},
created_date: {
type: Date,
default: Date.now
},
user : {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
});
module.exports = mongoose.model('Messages', msgSchema);
msgController
var mongoose = require('mongoose'),
Message = mongoose.model('Messages');
exports.list_all_messages = function (req, res) {
Message.find({})
.populate('user')
.exec((err, msg) => {
if (err)
res.send(err);
res.json(msg);
});
};

module.exports = mongoose.model('Users', userSchema);
maybe in msgSchema you have to reference 'users' instead of 'user'

So, I found the error in the code, in the user's schema there was a lack of reference to the export of the name that was placed in the user's model.
user : {
type: mongoose.Schema.Types.ObjectId,
ref: 'Users'
},
So,...
module.exports = mongoose.model('Users', userSchema);

Related

How to auto delete ObjectId referances in mongodb

im trying to auto delete notifications referance from users ,when notification gets deleted
the userSchema looks like
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
notifications: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Notification",
},
],
});
module.exports = mongoose.model("User", userSchema);
The notification model looks like this
const mongoose = require("mongoose");
const notificationSchema = new mongoose.Schema({
type: String,
created: {
type: Date,
default: Date.now,
},
});
notificationSchema.pre("deleteOne", function (next) {
this.model("User").deleteOne({ notifications: this._id }, next);
});
module.exports = mongoose.model("Notification", notificationSchema);
when i try to delete notification i get an error ,which looks like
ObjectParameterError: Parameter "obj" to Document() must be an object, got User
also is there a way to auto delete it [referances of notification in user] using TTL for notifications
ok ,after a few try and error. I came up with this solution..
const mongoose = require("mongoose");
const notificationSchema = new mongoose.Schema({
type: String,
created: {
type: Date,
default: Date.now,
},
});
notificationSchema.pre("deleteOne", function (next) {
let id = this.getQuery()["_id"];
mongoose.model("User").findOne(
{
notifications: id,
},
(err, res) => {
const index = res.notifications.findIndex((x) => x._id == id);
res.notifications.splice(index, 1);
res.save();
next();
}
);
});
module.exports = mongoose.model("Notification", notificationSchema);
Can i make any improvements ?

Error Message Cannot read property 'push' of undefined

i'm learning nodejs and so javascript and i've an error message when i execute node app.js. I'm already searching but still not find where i made a mistake :/
TypeError : Cannot read property 'push' of undefined at C:...\seeds.js:46:52
Here the code of seeds.js :
const mongoose = require("mongoose");
var Campground = require("./models/campground");
var Comment = require("./models/comment");
var data = [
{
name: "Cloud",
image: "http://rockwoodparkcampground.com/wp-content/uploads/2015/10/campground_033.jpg",
description: "bla bla bla"
},
{
name: "Desert",
image: "http://rockwoodparkcampground.com/wp-content/uploads/2015/10/campground_033.jpg",
description: "bla bla bla"
}
]
function seedDB() {
//Remove all campgrounds
Campground.remove({}, (err) => {
if (err) {
console.log(err);
}
console.log("bla");
// add campgrounds
data.forEach(function (seed) {
Campground.create(seed, function (err, campground) {
if (err) {
console.log(err);
} else {
console.log("added a campground");
// create a comment
Comment.create(
{
text: "This place is great, but I wish there was internet",
author: "Hermione Granger"
}, function (err, comment) {
if (err) {
console.log(err)
} else {
campground.comments.push(comment);
campground.save();
console.log("Created a new comment");
}
});
}
});
});
});
}
module.exports = seedDB;
Here comments.js :
const mongoose = require("mongoose");
var commentSchema = mongoose.Schema({
text: String,
author: String
});
module.exports = mongoose.model("Comment", commentSchema);
Here campground.js
const mongoose = require('mongoose');
var campgroundSchema = new mongoose.Schema({
name: String,
image: String,
description: String
});
module.exports = mongoose.model("Campground", campgroundSchema);
And finally the top of app.js
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
var Campground = require("./models/campground");
var seedDB = require("./seeds")
seedDB();
mongoose.connect('mongodb://localhost/beer_n_camp');
app.use(bodyParser.urlencoded({extended: true}));
app.set("view engine", "ejs");
app.use(express.static(__dirname + '/views'));
Please define comment in campground schema
var mongoose = require('mongoose');
var campgroundSchema=mongoose.Schema({
name:String,
image:String,
description:String,
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Comment'
}
]
});
module.exports =mongoose.model("Campground",campgroundSchema);
I had also faced the same issue on the web developer Bootcamp course.
Just define the comments in the campgroundSchema in the campground.js file.
const mongoose = require('mongoose');
var campgroundSchema = new mongoose.Schema({
name: String,
image: String,
description: String
comments: [ { type: mongoose.Schema.Types.ObjectId, ref: 'Comment' } ]
});
module.exports = mongoose.model("Campground", campgroundSchema);

Mongoose save doesn't work "id is not defined"

It's my first time using Mongoose and the save function is not working for me...
On user model file:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = mongoose.model('User', {
name: Schema.Types.Mixed,
gender: String,
email: String
});
module.exports = User;
On my user controller file:
// Create a user
router.post('/', function(req, res) {
var user = new User(req.body);
user._id = mongoose.Types.ObjectId();
user.save(function(err) {
if (err) {
return res.status(500).json({
error: "Error creating user: " + err
});
}
return res.status(200).end();
});
});
I tried everything but I can't save the user object to the database: "id is not defined"
On the db the _id is a ObjectId.
Thanks.
mongoose.model receives collection name and a Schema as arguments, not an regular object.
So you should use the following code instead:
var schema = new mongoose.Schema({
name: Schema.Types.Mixed,
gender: String,
email: String
});
var User = mongoose.model('User', schema);
maybe we can change the code structure && remove "user._id", test please this code :
*model file:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
name: Schema.Types.Mixed,
gender: String,
email: String
});
module.exports = mongoose.model('User', UserSchema);
*controller file:
// Create a user
router.post('/', function(req, res) {
var user = new User(req.body);
user.save(function(err) {
if (err) {
return res.status(500).json({
error: "Error creating user: " + err
});
}
return res.status(200).end();
});
});

Mongoose error: Schema hasn't been registered for model when populate

I am trying to join two collections and being able to get the combined data. To do so using Mongoose, i am supposed to use the populate syntax to achieve that. I am receiving error that the Schema Schema hasn't been registered for 'User_Fb'. From my code, I have exported the models and required in my server.js but the error is still appearing. What have I done wrong?
feed_post.model.js
var mongoose = require('mongoose');
var conn_new_app = mongoose.createConnection('mongodb://localhost/new_app');
var User_fb = require('../models/fb_db.model');
var Schema = mongoose.Schema;
var feed_postSchema = new Schema({
user_id: { type: Schema.Types.ObjectId, ref: 'User_Fb' },
content: String,
location: String,
image: [{ type : String }]
});
var Feed_Post = conn_new_app.model('Feed_Post', feed_postSchema);
module.exports = Feed_Post;
fb_db.model.js
var mongoose = require('mongoose');
var conn_new_app = mongoose.createConnection('mongodb://localhost/new_app');
var Feed_Post = require('../models/feed_post.model');
var user_fb = new mongoose.Schema({
name: String,
location: String,
fb_id: Number
});
var User_Fb = conn_new_app.model('User_Fb', user_fb);
module.exports = User_Fb;
server.js
var express = require('express'),
mongoose = require('mongoose'),
User = require('./app/models/user.model'),
Post = require('./app/models/post.model'),
Maptest = require('./app/models/maptest.model'),
Feed_Post = require('./app/models/feed_post.model'),
User_Fb = require('./app/models/fb_db.model'),
app = express();
app.get('/testget', function(req,res){
Feed_Post.findOne().populate('user_id').exec(function(err, c) {
if (err) { return console.log(err); }
console.log(c.fk_user.userName);
});
});
UPDATED from Pier-Luc Gendreau Answer's
fb_db.model.js
module.exports = function (connection) {
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var user_fb = new mongoose.Schema({
name: String,
location: String,
fb_id: Number
});
return connection.model('User_FB', user_fb);;
}
feed_post.model.js
module.exports = function (connection) {
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var feed_postSchema = new Schema({
user_id: { type: Schema.Types.ObjectId, ref: 'User_Fb' },
content: String,
location: String,
image: [{ type : String }]
});
return connection.model('Feed_Post', feed_postSchema);;
}
server.js
var express = require('express'),
app = express(),
mongoose = require('mongoose'),
conn_new_app = mongoose.createConnection('mongodb://localhost/new_app'),
User_Fb = require('./app/models/fb_db.model')(conn_new_app),
Feed_Post = require('./app/models/feed_post.model')(conn_new_app);
app.get('/testget', function(req,res){
Feed_Post.find().populate('user_id').exec(function(err, res) {
if (err) { return console.log(err); }
console.log(res);
});
});
This is all I had to do Customer.findOne({}).populate({ path: 'created_by', model: User }) instead of this Category.findOne({}).populate({'author'})
IF YOU (really) USE MULTIPLE mongoDB CONNECTIONS
I do realise that this is not the case for the OP, but if you genuinely use multiple connections you MUST provide the model when using .populate(), as mongoose will only "find" models on the same connection.
ie where:
var db1 = mongoose.createConnection('mongodb://localhost:27017/gh3639');
var db2 = mongoose.createConnection('mongodb://localhost:27017/gh3639_2');
var userSchema = mongoose.Schema({
"name": String,
"email": String
});
var customerSchema = mongoose.Schema({
"name" : { type: String },
"email" : [ String ],
"created_by" : { type: mongoose.Schema.Types.ObjectId, ref: 'users' },
});
var User = db1.model('users', userSchema);
var Customer = db2.model('customers', customerSchema);
Correct:
Customer.findOne({}).populate('created_by', 'name email', User)
or
Customer.findOne({}).populate({ path: 'created_by', model: User })
Incorrect (produces "schema hasn't been registered for model" error):
Customer.findOne({}).populate('created_by');
The problem is that you are creating a new connection in each and every model, so you end up with a bunch of different connection objects. Even though they are pointing to the same database, mongoose models don't know about other connections. You should instead create the connection object in your main app and then pass it around.
server.js
var express = require('express');
var mongoose = require('mongoose');
var app = express();
var conn_new_app = mongoose.createConnection('mongodb://localhost/new_app');
var Feed_Post = require('./app/models/feed_post.model')(conn_new_app);
app.get('/testget', function(req,res){
Feed_Post.findOne().populate('user_id').exec(function(err, c) {
if (err) { return console.log(err); }
console.log(c.fk_user.userName);
});
});
Then modify your models so they are actually a function:
feed_post.model.js
module.exports = function (connection) {
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var feed_postSchema = new Schema({
user_id: { type: Schema.Types.ObjectId, ref: 'User_Fb' },
content: String,
location: String,
image: [{ type : String }]
});
return connection.model('Feed_Post', feed_postSchema);;
}
Also, like Adrian mentions, you can use mongoose as a singleton. However, I do recommend using createConnection as you did because if you ever need a second connection, you won't have to refactor the connection code to your first database.
It looks like you are creating a different database connection for each model, which isolates the models from each other. Mongoose must assume this isolation, because they could exist on different databases or even database servers.
Try connecting once, and just calling mongoose.model() instead of connection.model() when defining your models. Mongoose is a singleton by default.
In my case, this issue because I haven't included the ref model into the application.
You can get the field you want by using select
Example to get the email of the customer:
Customer.findOne({}).populate({ path: 'created_by', model: User, select: 'email' })
More Details in mongoose documentation

Mongoose TypeError: object is not a function when instantiating object of a schema type

the issue i'm having is that mongoose isn't letting me instantiate an object of a schema type, inside a 'pre' method, of a different schema.
I've got 2 schemas - 'User' and 'Tickit'.
User.js
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var Schema = mongoose.Schema;
var Tickit = require('../models/Tickit');
var userSchema = new Schema({
email : String,
password : String,
tickits : [Tickit.tickitSchema]
});
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.password);
};
module.exports = mongoose.model('User', userSchema);
and Tickit.js
var mongoose = require('mongoose');
var User = require('../models/User');
var Schema = mongoose.Schema;
var tickitSchema = new Schema({
title: String,
description: String,
author : { type: Schema.Types.ObjectId, ref: 'User' },
comments: [{body:"string", by: mongoose.Schema.Types.ObjectId}]
});
tickitSchema.pre('save', function(next){
var user = new User();
user.tickits.push ({id:this._id});
user.save(function(err){
if(err)
res.send(err)
.populate('tickits')
.exec(function(err, blah){
if(err) res.send(err);
})
res.json(blah);
})
next();
})
module.exports = mongoose.model('Tickit', tickitSchema);
What i'm trying to do with the pre method in Tickit is populate the 'Tickits' array in the User schema with the id of that Tickit every time a Tickit is created.
However in my app when I do create a tickit, the app crashes and I get this error
var user = new User();
^
TypeError: object is not a function
Try to define user inside your function:
tickitSchema.pre('save', function(next){
var User = require('../models/User');
// Code
});

Categories