Cannot overwrite `modelName` model once compiled - javascript

Cannot overwrite partnerCode model once compiled.
I have a file like models/partnerCode.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var partnerCodeSchema = new Schema({
email: String,
used: {type: Number, default: 0}
});
var partnerCode = module.exports = mongoose.model('partnerCode', partnerCodeSchema);
module.exports.add = function(code){
partnerCode.findOne({email:code},function(err,response){
console.log(response);
});
}
and in my app.js I try to add an end point to make rest POST
var PartnerCodeModel = require('./models/PartnerCode');
app.post('/PartnerCodeModel/add', PartnerCodeModel.add( function(req,res,next){
console.log('code: '+req.body.code);
}))
Above code won't work, I got Cannot overwrite partnerCode model once compiled why ?

It should work like this:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var partnerCodeSchema = new Schema({
email: String,
used: {type: Number, default: 0}
});
var partnerCode = mongoose.model('partnerCode', partnerCodeSchema);
module.exports.add = function(code){
partnerCode.findOne({email:code},function(err,response){
console.log(response);
});
}
If you need any further assistance then comment on this answer. I would like to help you. :-)

Related

TypeError: User is not a constructor

I am trying to save a user to mongodb database using post request as follow, but I got the error TypeError: User is not a function. It's a pretty simple set up of the code but i can't figure out anything wrong with it.
I am using:
mongoose 4.8.6
express 4.15.2
node 6.6
// models/user.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
email: {
type: String,
unique: true,
lowercase: true
},
password: String
});
// server.js
var User = require('./models/user');
app.post('/create-user', function(req, res, next) {
var user = new User(); // TypeError: User is not a constructor
user.email = req.body.email;
user.password = req.body.password;
user.save(function(err) {
if (err) return next(err);
res.json('Successfully register a new user');
});
});
You need to create model from your UserSchema and then export it, then you can create new User objects.
// models/user.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
email: {
type: String,
unique: true,
lowercase: true
},
password: String
});
module.exports = mongoose.model('User', UserSchema)
You got that error because you exported the modules wrongly,
In my case in the models/user I had written module.export leaving out the s at the end
When you run the code it then gives you that error
I would advice checking on your module.exports = mongoose.model('User', UserSchema) spellings
// models/user.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
email: {
type: String,
unique: true,
lowercase: true
},
password: String
});
var User = mongoose.model('User', UserSchema)
module.exports = { User } <-- capital 'U'
Changing the lowercase user variable into uppercase (like below) strangely worked:
const User = mongoose.model('users');
I really thought this was just a best practice but eventually, seems to be mandatory.
Change this var user = new User(); for this var User = new User();
I was also facing the same error but this worked for me.
I did change my export file
var User = mongoose.model('User',userSchema);
module.exports = {User};
To
module.exports = mongoose.model('User', userSchema);

Mongoose save() is not a function

In my app.js I require my model like
var User = require('./models/user');
app.post('/user/add', function(req,res,next){
var newUser = new User();
newUser.add(req.body.name, function(response){
res.json(response);
})
});
and my model (user.js) look like this
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
name: String
});
var User = module.exports = mongoose.model('user', userSchema);
module.exports.add = function(name,callback){
User.save({name:name}).exec(callback);
}
But I got error of newUser.add is not a function?
If you want to add instance methods to a mongoose Model you should use instance methods syntax:
var mongoose = require('mongoose');
var UserSchema = new mongoose.Schema({
name: String
});
// Instance methods
UserSchema.methods.add = function(name, callback){
this.name = name;
return this.save(callback);
}
module.exports = mongoose.model('User', UserSchema);
Methods can be added with methods keyword like this
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
name: String
});
userSchema.methods.add = function(name,callback){
User.save({name:name}).exec(callback); // not checking logic
}
var User = module.exports = mongoose.model('user', userSchema);
You can do it as follows:
var mongoose = require('mongoose');
var Schema = Mongoose.Schema;
//schema is declared here
var userSchema = new Schema({
name: String
});
var user = Mongoose.model('User', UserSchema);
//here we are assigning new data to user collection
//this record will not be saved here
//it will only check the schema is matching or not
//if record is matching to schema then it will assign '_id' to that record
var userRec = new user({"name":"Jessie Emerson"});
userRec.save(function(error, userDoc) {
//this is the callback function
});
If you need anymore clarifications then please comment on this answer. :-)

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
});

How to break code in modules in Node.JS?

I'm with the following code that needs to be used in two files:
var Schema = mongoose.Schema;
var InfoSchema = new Schema ({
name: String,
email: String,
});
var Info = mongoose.model('Info', InfoSchema);
I need use the Info variable in my listTerminal.js, and i need use the InfoSchema in my routes.js .
I'm new in Node.js, and still confuse me a lot the module.exports. Can anyone give me a light?
I was trying to do like this:
module.exports = function() {
var Schema = mongoose.Schema;
var InfoSchema = new Schema ({
name: String,
email: String,
});
};
Them call in my routes.js and listTerminal.js like this:
var mySchema = require('../config/mongo/mySchema');
But is not working, cause in my route.js, i have a route like this:
app.post('/person', function(req, res) {
var Data = {
name: req.body.name,
email: req.body.email
};
var info = new Info(Data);
info.save(function (error, data){
if (error) {
console.log(error);
}
else {
console.log('done');
}
});
});
And the page shows:
Info is not defined
How can i call this mySchema.js in another file??
OBS: if i move the myschema.js code to my route.js file, the route.js will work, but i need separate ;[
Your module should look like this:
var Schema = mongoose.Schema;
var InfoSchema = new Schema ({
name: String,
email: String,
});
module.exports = mongoose.model('Info', InfoSchema);
That way you're exporting the model, not the schema. Then you can use it like so:
var Info = require('../config/mongo/mySchema');
app.post('/person', function(req, res) {
var Data = {
name: req.body.name,
email: req.body.email
};
var info = new Info(Data);
info.save(function (error, data){
if (error) {
console.log(error);
}
else {
console.log('done');
}
});
});
When you do
var mySchema = require('../config/mongo/mySchema');
then mySchema becomes what module.exports is. Since it is a function (in your case) then you have to simply call it:
mySchema();
BTW: I don't know why you defined it as a function. Might not be the best idea.

Categories