Mongoose error being returned as undefined? - node.js

I am trying to test my db connection with jasmine.
MongoClient is an object and is defined. However err returns undefined, naturally my test fails. Does Mongoose simply return undefined if there is no error?
Is there another way to check for the connection?
describe("MongoDB", function() {
it("is there a server running", function(next) {
var MongoClient = require('mongoose');
MongoClient.connect('mongodb://127.0.0.1:27017/panther_dev', function(err) {
expect(err).toBe(null);
next()
});
});
});
Thank you

Another way to check your connection is to use Connection#readyState. It returns one of four values which are:
0 = disconnected
1 = connected
2 = connecting
3 = disconnecting
So in your example, to test for a connection, it would look something like:
it("is there a server running", function(next) {
var MongoClient = require('mongoose');
MongoClient.connect('mongodb://127.0.0.1:27017/panther_dev', function(err) {
expect(MongoClient.readyState).toBe(1);
next();
});
});

Related

uable to connect to mongdb Atlas from nodejs using mongoose

This is the error I am getting . please help to resolve this
Code
const MongoClient = require('mongodb').MongoClient;
const uri = "mongodb+srv://userName:password#saichaitanyacluster-1m22k.mongodb.net/test?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true });
client.connect(err => {
const collection = client.db("test").collection("devices");
client.close();
});
You should add a check to confirm that there is no error in connection before calling client.db(). The connection code should be something like this:
// ...Everything that was here before
client.connect(err => {
if (err) {
console.log("There was an error connecting to the database");
// Any other logic that you want to use to handle the error should live here.
// Add a return statement to help avoid executing
// the code below that relies on a successful connection
return;
}
const collection = client.db("test").collection("devices");
client.close();
});
I hope this helps.

Connect synchronously to mongodb

I would like to connect to mongodb first, then run everything else in my application.
To do it I have to write something like:
MongoClient.connect("mongodb://localhost/test", function(err, connection) {
if (err) { console.error(err); }
db = connection;
var app = express();
// Include API V1
require("./apiv1.js")(app, db);
app.listen(3000, function(err) {
if (err) { console.error(err); } else { console.log("Started on *:3000"); }
});
});
This makes my app to be completely indented inside the .connect function... Which looks ugly and takes space while I work on my project.
I think the best solution would be have the MongoDB connection synchronous (even because witout the DB connection my app cannot work so why should I do something while it's connecting?) and then run the rest of my code.
How can I do?
You can't connect to MongoDB synchronously, but you may get rid of this ugly callback from your code.
The best way to do it is to adopt some wrapper around node-mongodb-native driver.
Take a look at the following modules.
mongojs
var mongojs = require('mongojs');
var db = mongojs('localhost/test');
var mycollection = db.collection('mycollection');
mongoskin
var mongo = require('mongoskin');
var db = mongo.db("mongodb://localhost:27017/test", {native_parser:true});
monk
var monk = require('monk');
var db = monk('localhost/test');
var users = db.get('users')
Of course, internally all of them are establishing MongoDB connection asynchronously.
Using the async library, you can aleve some of these issues.
For example in my server startup I do the following :
async.series([
function(callback){
// Initialize the mongodb connection and callback on completion in init.
db.init(function(){
callback();
});
},
function(callback){
// Listen on requests etc.
webServer.init(function(){
callback();
});
},
function(callback){
// Set up anything else that I need
callback();
}
]);
If you are using Node 6 and up versions, you can do something like this:
const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017/mydb';
let db = null;
getdb();
//your code
async function getdb() {
db = await MongoClient.connect(url);
}
Bring the mongodb library.
Declare the url constant .
Declare the variable db as null.
Call the getdb function.
Create the getdb function which has firt the async word
Assign to the db variable the result of the connection with the key word await.
You can do it with thunky, thunky executes an async function once and caches it, the subsequent calls are returned from the cache.
const MongoClient = require('mongodb').MongoClient;
const thunky = require('thunky');
var connect = thunky(function(cb){
let url = 'mongodb://localhost:27017/test';
MongoClient.connect(url, function(err, client){
console.log('connecting')
cb(err, client);
})
})
connect( (err, client) => {
console.log('connection 1')
})
connect( (err, client) => {
console.log('connection 2')
})
connect( (err, client) => {
console.log('connection 3')
console.log('closing')
client.close();
})
*Note: I am using latest 3.x mongodb driver

Unable to persist data using nodejs mongoosejs to mongodb

I am currently unsuccessfully trying to persist document to mongodb using nodejs and mongoosejs.
This my code structure:
The start.js simply initializes my app and creates mongod connection detailed in mongodb.js. The connection is succesfully established and can be seen in mongodb console.
this my model.js
var mongoose = require('mongoose');
var regSceham = new mongoose.Schema({
userId: String,
name:String,
mob:String,
email:String
})
var RegistrationModel = mongoose.model('registration', regSceham);
exports.RegistrationModel = RegistrationModel;
this is my datalayer.js:
var mongoose = require('mongoose');
var mongodb = require('./mongodb');
var model = require('./model');
//var RegistrationModel = mongoose.model('RegistrationModel');
/////////////////////////////////
function save(data){
console.log('inside save >>>>> ' + data);
var regModel = new model.RegistrationModel(data);
console.log('after model');
regModel.save(function(err,regModel){
console.log('inside mongoose save');
if(err)
console.log(err);
});
}
require('./model')
exports.save = save;
when I call the save method in datalayer.js the "inside save >>>>> " statement logged to console and then nothing happens. It seems the var regModel = new model.RegistrationModel(data); statement fails without any error and I donot have any clue why. Any suggestion would be highly appreciated.
sample post data as requested :
{
"userId":"tesrwetId",
"name":"Test",
"mob":"2536245632",
"email":"ashdjas#sa.com"
}
Update 24/06
I am starting to think that since the connection to mongoose is established after my model initialization this problem is experienced. I am unable to get the connection to happen before model is initialized.
Below is the file initialisation sequence. Though the mongodb.js(the mongoose connection) is initilaized first, the on connect method gets called after model.js is initialized.
The mongodb.js file:
console.log('mongodb....');
var mongoose = require('mongoose');
var configure = require('./configure');
// create database
//console.log('sadasdasdsa >>>>>>>' + configure.creds.mongodb)
mongoose.connect(configure.creds.mongodb);
mongoose.connection.on('connected', function () {
console.log('MOngodb connection open to ' + configure.creds.mongodb);
require('./model');
});
// If the connection throws an error
mongoose.connection.on('error',function (err) {
console.log('MOngodb connection error: ' + err);
});
// When the connection is disconnected
mongoose.connection.on('disconnected', function () {
console.log('MOngodb connection disconnected');
});
process.on('SIGINT', function() {
mongoose.connection.close(function () {
console.log('MOngodb connection disconnected through app termination');
process.exit(0);
});
});
require('./model');
update 28/06
I have since realised this understanding regarding loading sequence is incorrect. read here
Might have something to do with you're connection using the mongodb library and then trying to save using mongoose. Mongoose has mongodb as a dependency and is probably not resolving to the connection you've made. Remove your mongodb code and use the mongoose connect() function to establish db connection.
something like:
mongoose.connect('mongodb://localhost:port/test', function(err){
if(err) console.log(err);
else console.log('Connected');
});

how to set connection timeout for mongodb thru node.js

The following is the connection string and options i'm using from node.js to connect to mongodb. My web application keeps re-trying and never posts back if the mongodb server is down. Where do I set the connection timeout so I can say db server is down when it is? (The following code works perfectly when the mongo server is up).
(function(database) {
var mongodb = require("mongodb");
database.ObjectID = mongodb.ObjectID;
var mongoUrl = "mongodb://localhost:27017/mydb";
var dbconn = null;
database.getDBConn = function(next){
if(dbconn){ next(null, dbconn); return; } //already connected: return dbconn
mongodb.MongoClient.connect(mongoUrl,
{server: {socketOptions: {connectTimeoutMS: 500}}}, function(err, database){
if(err){ next(err, null); return; } //connection fail: return error
dbconn = {db: database,
movies: database.collection("movie") };
next(null, dbconn); //connection success: return dbconn
});
}
})(module.exports);
Looking at http://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html I would say use
MongoClient.prototype.close
method to check if the connection is closed.If the connection is closed then emit a notification that the database server is down.

How to correct the “connection.readyState” of mongoose in mocha from “connecting” to “connected?

When I am trying to run the mocha test i am getting "Cannot determine state of server"
since the mongoose connection is in connecting state.
Please suggest how to handle this scenario.
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
console.log('conn ready: '+mongoose.connection.readyState);
// "conn ready: 2" i.e connecting for test case as well as from user register form
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId,
UserSchema = new Schema({
// schemas
});
UserSchema.statics.newUser = function (uname, email, pass) {
var instance = new User();
instance.uname = uname;
instance.email = email;
instance.pass = pass;
console.log("conn state: "+mongoose.connection.readyState);
// "conn state: 2" i.e connecting for test case. But 1 i.e connected for user register form
instance.save(function (err) {
// Do rest
});
};
var User = mongoose.model('User', UserSchema);
exports.User = User;
DB connections happens asynchronously so when you check up on it straight after calling connect it's likely going to report that it's still connecting. If you want to do something after connection, you need to pass in a callback
mongoose.connect('mongodb://localhost/test', function (error) {
// Do things once connected
});
As for how to handle it in your scenario, my suggestion is to separate connection from your models and connect to MongoDB when required
So if you're testing your user model in mocha, this could be done in the Before hook
var mongoose = require("mongoose");
// Load in your user model wherever that is
var User = require("../models/user");
describe("My user model tests", function () {
// Connect to mongodb here before you start testing
before(function (done) {
mongoose.connect('mongodb://localhost/test', function (error) {
if (error) throw error; // Handle failed connection
console.log('conn ready: '+mongoose.connection.readyState);
done();
});
});
// And include disconnect afterwards
after(function (done) {
mongoose.disconnect(done);
});
// Test your user model down here
it("passes some tests");
});
Depending on how you've structured your app, I'd suggest you move DB connection to a sensible location (e.g. server configuration). When you test your entire app (e.g. integration testing), you would start your server in the Before hook
In addition, if you have your mongoose connection routines in another file (like me), during the asynchronous nature of JS, you should wait a little for the readyState to be 'connected' (1). I solved it in 'before':
var app = require('../server'); //I have mongoose connection in this file
var mongoose = require('mongoose');
var context = describe;
describe('Initial DB routines', function() {
before(function (done) {
mongoose.connection.on('connected', done);
});
it('Should connect to MongoDB', function(done) {
mongoose.connection.readyState === 1 ? done(): done(false);
});
});

Resources