Nodejs include Models - node.js

Im having problems to make my server.js use my models.
I do have other models with same structure, like for example:
var Post = mongoose.model('Post');
var Comment = mongoose.model('Comment');
but they works fine.. somehow.
But if If i try to use:
var Crime = mongoose.model('Crime');
i get:
throw new mongoose.Error.MissingSchemaError(name);
^
MissingSchemaError: Schema hasn't been registered for model "Crime".
if i switch to:
var Crime = require('./models/Crime');
or
var Crime = require('./models/Crime.js');
i get the response:
Cannot find module './models/Crime'
Crime model code:
var mongoose = require('mongoose');
var CrimeSchema = new mongoose.Schema({
username: {type: String, lowercase: true, unique: true},
time: String,
salt: String
});
CrimeSchema.methods.performCrime = function(pass) {
/*var deferred = $q.defer();
deferred.notify('loading....');
deferred.reject('Greeting is not allowed.');
return deferred.promise;
*/
return 22;
};
mongoose.model('Crime', CrimeSchema);
EDIT
example of working model:
var Post = mongoose.model('Post');
and post.js model
var mongoose = require('mongoose');
var PostSchema = new mongoose.Schema({
title: String,
link: String,
upvotes: {type: Number, default: 0},
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }]
});
PostSchema.methods.upvote = function(cb) {
this.upvotes += 1;
this.save(cb);
};
PostSchema.methods.downvote = function (cb) {
this.upvotes -= 1;
this.save(cb);
};
mongoose.model('Post', PostSchema);

You forgot to export the module at the end.
var Crime = mongoose.model('Crime', CrimeSchema);
module.exports = Crime;

Related

Generate test data from mongoose model

I have this model in nodejs app
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var ServiceSchema = new Schema({
Taxy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Taxy',
required: 'Taxy cannot be blank'
},
User: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: 'User cannot be blank'
},
Servicio: String,
Minutos: Number,
Costo: Number,
Desc: String,
From: String,
To: String,
created: {
type: Date,
default: Date.now
}
});
mongoose.model('Service', ServiceSchema);
I have surfed for a couple of days and I have not found a framework to generate random data from a model service, something like
var Service = require('mongoose').model('Admin').schema;
var jsondata = generateRandomeFromModel(Service)
You can use mongoose-fakery module to generate test data
Example:
var mongoose = require('mongoose')
, Schema = mongoose.Schema;
var UserSchema = new Schema({
name: String,
surname: String
});
mongoose.model('User', UserSchema);
In your tests or fixture files:
var fakery = require('mongoose-fakery');
fakery.fake('user', mongoose.model('User'), {
name: 'john',
surname: 'doe'
});
You can go with complete reference here
You can use a package called Faker that makes it easier.
npm install #faker-js/faker --save-dev
get relational data by $sample (aggregation)
const { faker } = require('#faker-js/faker');
const mongoose = require('mongoose');
const getFakeData = async () => {
const taxy=await Model.Taxy.aggregate([{ $sample: { size: 1 } }]); //Randomly select document from `Taxy` Model
const user=await Model.User.aggregate([{ $sample: { size: 1 } }]);
return ({
Taxy: taxy.length && taxy[0]._id,
User: user.length && user[0]._id,
Servicio: faker.commerce.productAdjective(),
Minutos: faker.datatype.number(),
Costo: faker.datatype.number(),
Desc: String,
From: faker.name.findName(),
To: faker.name.findName(),
created: Date.now().toString()
});
}
const fakeJsonData = await getFakeData();
I found a working solution it was created 2 years ago. I tested it too it is working.
https://www.npmjs.com/package/mongoose-dummy

TypeError object is not a function

I'm developing an application in node.js with MongoDB
I have to files:
product.js and displaycost.js
this is product .js:
var mongoose = require('mongoose');
var Category = require('./category');
var productSchema = {
name:{type: String, require: true},
//Pictures mus start with "http://"
pictures:[{type:String, match: /^http:\/\//i}],
price:{
amount:{type: Number, required: true},
//ONly 3 supported currencies for now
currency:{
type: String,
enum:['USD','EUR','GBP'],
required: true
}
},
category: Category.categorySchema
};
var schema = new mongoose.Schema(productSchema);
var currencySymbols ={
'USD': '$',
'EUR':'€',
'GBP':'£'
};
/*
*
*/
schema.virtual('displayPrice').get(function(){
return currencySymbols[this.price.currency] +
'' + this.price.amount;
});
schema.set('toObject', {virtuals:true});
schema.set('toJSON', {virtuals:true});
module.exports = schema;
What I need is create a record with "productSchema"
I tried with this:
var Product = require('./product.js');
var p = new Product({
name: 'test',
price:{
amount : 5,
currency: 'USD'
},
category: {
name: 'test'
}
});
console.log(p.displayPrice); // "$5"
p.price.amount = 20;
console.log(p.displayPrice); //" $20"
//{... "displayPrice: "$20",...}
console.log(JSON.stringify(p));
var obj = p.toObject();
But when I run the displaycost.js throw me an error at the word "new"
and writes "TypeError: object is not a function"
I don't know why is happening that. Thank you.
you missing export mongoose model with model name.
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
Category = require('./category');
var productSchema = new Schema({
name: {type: String, require: true},
pictures: [{type: String, match: /^http:\/\//i}],
price: {
amount: {type: Number, required: true},
currency: {
type: String,
enum: ['USD', 'EUR', 'GBP'],
required: true
}
},
category: Category
});
var currencySymbols = {
'USD': '$',
'EUR': '€',
'GBP': '£'
};
productSchema.virtual('displayPrice').get(function () {
return currencySymbols[this.price.currency] +
'' + this.price.amount;
});
productSchema.set('toObject', {virtuals: true});
productSchema.set('toJSON', {virtuals: true});
module.exports = mongoose.model('Product', productSchema);
"new" can only be called on a function. not an object.
In program.js you are creating a new instance of the mongoose schema.
var schema = new mongoose.Schema(productSchema);
... more code ...
return schema;
In your other js file you require product. At this point in time product.js has returned an object to you. A new mongoose schema. It is an object which you are refering to as Product.
You then try to create a new instance of it by calling new on the product OBJECT. New cannot be called on an object literal. It can only be called on a function.
I don't believe you need to make a new instance of schema within product.js, just return the function that creates the schema. Then call new on it when you require it like you are in your second file.

Mongoose populate across 2 databases

I have a node app that uses 2 databases. One is the the Names and the other for the rest of all the data.
I have this connection setup:
// DATABASE CONNECTION
var APP_DB_URI = config.APP_DB; // mongodb://localhost:27017/app_db
var app_DB = mongoose.createConnection(APP_DB_URI);
var name_DB = app_DB.useDb(config.NAME_DB); // 'name_db'
This connection is working properly.
There's also no problem upon saving data to both app_db and names_db working perfect.
But the problem is this: when I try to query let say the Account model and then populate the referenced Name model, the populate process returns null.
Account schema:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var field = {
email: {type: String, unique: true},
password: {type: String, select: false},
name: {type: Schema.Types.ObjectId, ref: 'Name'},
}
var options = {
id: false,
versionKey: false
}
var schema = new Schema(field, options);
module.exports = mongoose.model('Account', schema);
Name schema:
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var field = {
firstName: {type: String, required: true},
middleName: {type: String, required: true},
lastName: {type: String, required: true},
suffix: {type: String, required: false,},
}
var options = {
id: false,
versionKey: false
}
var schema = new Schema(field, options);
module.exports = mongoose.model('Name', schema);
The query and population:
var app_db = *app_db instance passed to this controller*
var Account = app_db.model('Account');
Account.findOne({email:req.body.email})
.populate('name')
.exec(function (err, user) {
if(user){
// user.name returns null
}
})
Is there a special way to populate data from db1 the data from db2? Thanks.
Populate Mongo documents across databases feature added since mongoose v3.9.0. Per this across db populate test, you should different db name when model is called. Some sample codes as below. More details please refer to the test codes in the link.
var app_DB = mongoose.createConnection(APP_DB_URI);
var name_DB = app_DB.useDb(config.NAME_DB); // 'name_db'
// ...
module.exports = app_DB.model('Account', schema);
// ...
module.exports = name_DB.model('Name', schema);
Populate
.populate('name', '', Name)

How to update a object in mongodb using mongoose?

I have a Schema:
exports.participant = function(mongodb){
var participantSchema = new mongoose.Schema({
uniqueid: {type: String, unique: true},
channel: String,
conference: String,
calleridnum: String,
calleridname: String,
event: String,
status : { type: Boolean, default: 0 }
},{ collection: 'participants'});
var participant = mongodb.model('Participant', participantSchema);
return participant;
}
I have already tried how to update a object in mongodb via mongoose, but still it doesn't work for me.
I want to update status to 1
I am calling the update code here . .
the file location of my schema is: ../models/app.js
the file location of my update is: ../lib/update.js
This is my update code . .
var appInit = require('../app');
var logger = appInit.logger;
var basedir = appInit.basedir;
var connection = appInit.connection;
var mongodb = appInit.mongodb;
var handleAsteriskAmi = require(basedir+'/lib/handleasteriskami');
var asteriskAmi = new handleAsteriskAmi();
var handleHttpProc = require(basedir+'/lib/handlehttpproc');
var httpProc = new handleHttpProc();
function handleSocketio(){
this.init = function(io){
io.sockets.on('connection',function(socket){
if(socket){
logger.info("socket.io is connected");
}
socket.on('disconnect', function () {
logger.error("Socket.io is disconnected");
});
socket.on('action', function(data){
var result = JSON.parse(JSON.stringify(data));
asteriskAmi.listenActionConfbridge(result,function(response){
logger.info(JSON.stringify(response));
if(response.event=="originate"){
io.sockets.emit("response",response);
}
if(response.event=="confbridgemute" || response.event=="confbridgeunmute"){
io.sockets.emit("response",response);
mongodb.model("Participant").update(
{channel: response.channel},
{$set: {status: 1}}
);
}
if(response.event=="confbridgelock" || response.event=="confbridgeunlock"){
io.sockets.emit("response",response);
}
});
});
});
I believe you need to pass in a mongoose object in your participant function in ../models/app.js that you can then use to convert the participantSchema into a Model. Thus in your ../models/app.js, you can implement the participant function as
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
exports.participant = function(){
var participantSchema = new Schema({
uniqueid: {type: String, unique: true},
channel: String,
conference: String,
calleridnum: String,
calleridname: String,
event: String,
status : { type: Boolean, default: 0 }
},{ collection: 'participants'});
var participant = mongoose.model('Participant', participantSchema);
return participant;
}
Call the participant model in your ../lib/update.js:
var appInit = require('../app');
var Participant = appInit.participant();
Participant.update(
{channel: response.channel},
{$set: {status: 1}}
);

How to create interdependent schemas in Mongoose?

I have two Schemas and I want them to interact with eachother. For instance:
// calendar.js
var mongoose = require('mongoose');
var Scema = mongoose.Schema;
var Day = mongoose.model('Day');
var CalendarSchema = new Schema({
name: { type: String, required: true },
startYear: { type: Number, required: true }
});
CalendarSchema.methods.getDays = function(cb){
Day.find({ cal: this._id }, cb);
}
module.exports = mongoose.model('Calendar', CalendarSchema);
// day.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var Calendar = mongoose.model('Calendar');
var DaySchema = new Schema({
cal: { type: ObjectId, required: true },
date: { type: Number, required: true },
text: { type: String, default: 'hello' }
});
DaySchema.methods.getCal = function(cb){
Calendar.findById(this.cal, cb);
}
module.exports = mongoose.model('Day', DaySchema);
However, I get an error because each schema depends on the other one. Is there a way to get this working using Mongoose? I include them like this:
// app.js
require('./models/calendar');
require('./models/day');
I realize this is an ancient thread, but I'm sure posting the solution will help others down the road.
The solution is to export the module before requiring the interdependent schemas:
// calendar.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var CalendarSchema = new Schema({
name: { type: String, required: true },
startYear: { type: Number, required: true }
});
module.exports = mongoose.model('Calendar', CalendarSchema);
// now you can include the other model and finish definining calendar
var Day = mongoose.require('./day');
CalendarSchema.methods.getDays = function(cb){
Day.find({ cal: this._id }, cb);
}
// day.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var DaySchema = new Schema({
cal: { type: ObjectId, required: true },
date: { type: Number, required: true },
text: { type: String, default: 'hello' }
});
module.exports = mongoose.model('Day', DaySchema);
// same thing here. require after exporting
var Calendar = require('./calendar');
DaySchema.methods.getCal = function(cb){
Calendar.findById(this.cal, cb);
}
It really is that simple. Explanation by Brian Bickerton can be found here:
http://tauzero.roughdraft.io/3948969265a2a427cf83-requiring-interdependent-node-js-modules
It's nice to be able to use functions by name within a module instead of the lengthy module.exports.name. It's also nice to have a single place to look and see everything to be exported. Typically, the solution I've seen is to define functions and variables normally and then set module.exports to an object containing the desired properties at the end. This works in most cases. Where it breaks down is when two modules are inter-dependent and require each other. Setting the exports at the end leads to unexpected results. To get around this problem, simply assign module.exports at the top, before requiring the other module.
You need require the files. If they are in the same path do this:
//calendar.js
var Day = require('./day');
/* Other logic here */
var CalendarSchema = new Schema({
name: { type: String, required: true },
startYear: { type: Number, required: true }
})
, Calendar;
/* other logic here */
/* Export calendar Schema */
mongoose.model('Calendar', CalendarSchema);
Calendar = mongoose.model('Calendar');
exports = Calendar;
Do the same in day.js
EDIT: As JohnnyHK says this don`t work. Link to explanation

Resources