Schema method for all Schema's - Mongoose method inheritance - javascript

I'm working in nodejs with Mongoose, at this moment I have data in different collections with _id like string writing for the user, I try to make a refactor of this and generate _id automatically.
I want have in other file js only function generateID( return _id; ); and implement this function in all models without write over and over in all models.
This is bus.js
/***********************************Bus Model**********************************/
var mongoose = require('mongoose'),
merge = require('merge'),
global = require('./schema/global');
/***********************************Schema******************************************/
var Schema = mongoose.Schema;
var busSchema = new Schema({});
/***********************************Methods*****************************************/
var bus = mongoose.model('Bus', busSchema);
/**
* extend functions from global
* we do this to prevent duplicate code
*/
merge(bus.schema.methods, global.schema.methods);
module.exports = bus;
And this is global.js in schema folder over models folder in project
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var globalSchema = new Schema({});
function objectIdAsString() {
return mongoose.Types.ObjectId().toString();
}
globalSchema.methods.objectIdAsString = objectIdAsString;;
module.exports = mongoose.model('global', globalSchema);
And in route.js have this implementation:
var bus = new Bus();
bus._id = bus.objectIdAsString();

Solution is creating a Mongoose plugin
http://mongoosejs.com/docs/plugins.html
global.js
var mongoose = require('mongoose');
module.exports = exports = function objectIdAsString(schema) {
schema.methods.objectIdAsString = function objectIdAsString() {
return mongoose.Types.ObjectId().toString();
};
}
bus.js
/***********************************Bus Model**********************************/
var mongoose = require('mongoose'),
merge = require('merge'),
global = require('./schema/global');
/***********************************Schema******************************************/
var Schema = mongoose.Schema;
var busSchema = new Schema({});
/**
* extend functions from global
* we do this to prevent duplicate code
*/
busSchema.plugin(global);
module.exports = mongoose.model('Bus', busSchema);
Somewhere else:
var bus = new bus();
console.log(bus.objectIdAsString());
Is working and outputting the correct values for me:
566b35a02a54c60e168c3a9f
566b35a02a54c60e168c3aa1
566b35a02a54c60e168c3aa3
.....

Related

Insert an array of objects into mongodb with nodejs

Now I am using clmtrackr library to detect emotions from the webcam and I want to save this emotions Here is my node.js code to save the values in mongodb
exports.storeemotion = function (emotions, callback){
var eshema= new emotioncollection({
emotions: [emotions]
});
eshema.save(function(err) {
});
callback({"status":"emotion remote done"});
}
and the schema code is
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//var bcrypt = require('bcrypt-nodejs');
// search results schema
var ResultaSchema = new Schema({
emotions:[{emotion: String, value: String}]
});
module.exports = mongoose.model('emotioncollection',ResultaSchema);
emotions should be like that (check this image).
but the mongo saved an empty array (check this image).
The emotions parameters of your storeemotion function is already an array, so you just have to pass that parameters as is, not in another array:
exports.storeemotion = function (emotions, callback) {
var eshema = new emotioncollection({
emotions: emotions // <= your schema already expects an array of objects
});
eshema.save(function(err) {
if (err) return callback({"status": "error"});
callback({"status": "emotion remote done"});
});
}

Getting database information from other file

I have 3 different files called: app.js, ServerManager.js and Users.js.
To start everything, I run app.js which runs my ServerManager.
Running ServerManager in App.js:
var ServerManager = require('./modules/ServerManager.js');
var serverManager = new ServerManager({
app: app,
path: __dirname
});
Then serverManager is called and I can do stuff in there, then I'm trying to send stuff to Users.js from ServerManager but it seems like it doesn't work.
ServerManager.js
var config = require('../config.js');
var express = require('express');
var colors = require('colors');
var DatabaseManager = require('../modules/DatabaseManager.js');
var RouteManager = require('../modules/RouteManager.js');
var Users = require('../data/users.js');
module.exports = function(options){
return new ServerManager(options);
}
var ServerManager = function (options) {
var self = this;
this.app = options.app;
this.options = options;
this.dbManager = new DatabaseManager();
this.dbManager.use();
this.RoutesManager = new RouteManager(this.app);
this.RoutesManager.use();
this.usersManager = new Users(this);
}
ServerManager.prototype.getDatabase = function () {
return this.dbManager();
}
Users.js - Marked in code what it can't find.
module.exports = function (ServerManager) {
return new Users(ServerManager);
};
var Users = function (ServerManager) {
var self = this;
this.serverManager = ServerManager;
};
Users.prototype.createUser = function (username, email, password) {
this.serverManager.getDatabase(); <--- Can't find getDatabase()
};
I think that you should change your Users.js code to:
// This is the Users object
// and this function is its constructor
// that can create users instances
var Users = function (ServerManager) {
var self = this; this.serverManager = ServerManager;
};
// We define a method for the user object
Users.prototype.createUser = function (username, email, password) {
this.serverManager.getDatabase();
};
// We export the user object
module.exports = Users;
Now the then you do
var Users = require('../data/users.js');
you get the User object.
And so, you can do new Users(...).
The same thing has to be done for the ServerManager.
If you want to use your code as it is, you don't have to use the new keyword on the imported object.

Issues while trying to implement multi tenant system using node.js with mongodb

We have different clients and the idea is to keep their data separate from each other in the same application. We are using node.js with mongodb and mongoose is being used for querying.
This is 'index.js' file in models directory
var mongoose = require('mongoose');
var fs = require('fs');
var connectionUrl = 'mongodbserverlink/';
var companies = [{ db: 'comp1_db', comp_id: 'com1' }, { db: 'com2_db', comp_id: 'com2' }, { db: 'com3_db', compa_id: 'com3'}];
var connections = {};
var models = {};
fs.readdirSync(__dirname)
.forEach(function (file) {
var Schema = file.split('.js')[0];
if (Schema === 'index') return;
models[Schema] = require('./' + Schema);
});
companies.forEach(function (company) {
var conn = mongoose.createConnection(connectionUrl + company.db);
connections[company.company_id] = {};
Object.keys(models).forEach(function (Schema) {
connections[company.company_id][Schema] = conn.model(Schema, models[Schema]);
});
conn.on('error', console.error.bind(console, company.db + ' connection error in mongodb in the first step!'));
conn.once('open', function() {
console.log(company.db + " mongodb connected");
});
});
module.exports = connections;
Here the connection is being made with different databases. The models directory has this index file.
Now in the controller where application logic is being done, this is what we are doing.
var models = require('../models');
var comp_id = req.body.comp_id;
db.collectionname.find...(This is not the syntax for find, I just cut it short to keep it simple) // -> this is not working now
when we tried logging models object this is what we got
models object is: {"com1":{},"com2":{},"com3":{}}
and only db when logged gives {}
We are facing issues in grasping the complete work... it is because the person who wrote the major chunk is not with us and there is no documentation.
What are we doing wrong here?
It looks like you already have your models exported from the index file. So, in the controller you can do a var models = require('index');. From the connections object, you may be able to retrieve the corresponding model: var companyModel = models[comp_id];.
Hope it helps.

Cucumber + Mongoose is giving me Schema hasn't been registered for model

The error message:
MissingSchemaError: Schema hasn't been registered for model "User".
Use mongoose.model(name, schema)
at Mongoose.model (/Users/JimBarrows/Desktop/TaskVelocity/cucubmer/node_modules/mongoose/lib/index.js:349:13)
at Object.<anonymous> (/Users/JimBarrows/Desktop/TaskVelocity/cucubmer/features/support/hooks.js:3:21)
My world.js file:
/**stuff**/
var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
require('../../../public_ui/models/Users');
var User = mongoose.model('User');
mongoose.connect('mongodb://192.168.99.100:27017/task_velocity');
As I understand it, this should setup mongoose quite nicely. Then in hooks.js:
'use strict';
var mongoose = require('mongoose');
var User = mongoose.model('User');
I've tried, in the hooks.js file:
'use strict';
var mongoose = require('mongoose');
require('../../../public_ui/models/Users');
var User = mongoose.model('User');
but that gives me the same error when I try to get ahold of the model.
Any ideas on what I'm doing wrong?
Jim Barrows, considering that the error is:
MissingSchemaError: Schema hasn't been registered for model "User".
and that your world.js has the following lines:
require('../../../public_ui/models/Users');
var User = mongoose.model('User');
I believe that is just a typo error and you could fix it easily by doing the following:
var User = mongoose.model('Users'); // instead of var User = mongoose.model('User');
**which by the way is exactly what dafyk commented in your post (not an answer) some days ago...
Hope this helps
I'm not sure, but...
check this link
You have to make schema and set mongoose.model('User',schema);
Can you show me "Users.js" source?;
If you want make module,
like this source
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
username: String,
passwrod: String
//Have to Custom
});
module.exports = mongoose.model('User', UserSchema);
and use this
var Users = require('../../../public_ui/models/Users');

Mongoose MissingSchemaError happening inconsistently with Mocha test

In users.spec.js I have this and it works fine:
var mongoose = require('mongoose');
var assert = require('assert');
var request = require('supertest');
var app = require('../../app.js');
var User = mongoose.model('User');
var Local = mongoose.model('Local');
var agent = request.agent(app);
var invalidId = 'aaaaaaaaaaaaaaaaaaaaaaaa';
In app.js I have:
mongoose.connect(dbUrl);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'Problem connecting to database.'));
db.once('open', function onDbConnect() {
console.log('Connected to ' + dbUrl + ' database...');
// create models
require('./api/users/user.model.js');
And in user.model.js I have:
var User = mongoose.model('User', userSchema);
var Local = mongoose.model('Local', localSchema);
So when users.spec.js is run, it first creates the models, and then I can reference them by mongoose.model('User') and mongoose.model('Local').
However, in auth.spec.js, I'm doing the same thing, and it's not working:
var mongoose = require('mongoose');
var assert = require('assert');
var request = require('supertest');
var app = require('../../app.js');
var User = mongoose.model('User');
var Local = mongoose.model('Local');
var agent = request.agent(app);
Output:
/Users/azerner/code/mean-starter/node_modules/mongoose/lib/index.js:332
throw new mongoose.Error.MissingSchemaError(name);
^
MissingSchemaError: Schema hasn't been registered for model "User".
Use mongoose.model(name, schema)
at Mongoose.model (/Users/azerner/code/mean-starter/node_modules/mongoose/lib/index.js:332:13)
at Object.<anonymous> (/Users/azerner/code/mean-starter/server/api/auth/auth.spec.js:5:21)
Why is this? I'm running the tests separately: mocha server/api/auth and mocha server/api/users, so they shouldn't be interfering with one another.
Full code here.
Note: this works, but I'd prefer not to use it. Or at least I'd like to understand what the problem is and why this works.
// :( https://github.com/Automattic/mongoose/issues/1251
// it isn't exactly my issue, but the recommendation on the bottom works
try {
var User = mongoose.model('User');
var Local = mongoose.model('Local');
}
catch(e) {
var schemas = require('../users/user.model.js');
var User = mongoose.model('User', schemas.UserSchema);
var Local = mongoose.model('Local', schemas.LocalSchema);
}

Categories