1. 2016
    Feb
    27

    Using Mongoose to connect with Express (nodeJS)

    Posted By


    mongoose nodejs

    Been exploring nodeJS and ran into a seemingly easy but irritating problem that had to do with connecting to MongoDB using Mongoose.

    Mongoose

    Mongoose is a node.js Object Document Mapper (ODM) that is written on top of the native Node.js MongoDB driver. One of the advantages of using an ODM is that it allows the developer define schema for documents in the database which can be mapped to objects in your program.

    Now web client should be able to call your server in such a way that the web server should be able to tell it if the database its connecting to is available or not. Simple right!? Not exactly! Mongoose works on the web server handling connections to your MongoDB database, it seems like its connection errors were meant to be thrown to the web server and not out to the web client.

    In order to make this work, I used mongoose.connect(connectionString, options) method to make sure I had a singleton connection. First create connection file.

    db.js

    
    
    var mongoose = require('mongoose'),
    	dbuser = 'MONGODB_USER',
    	dbpass = 'MONGODB_PASS',
    	dbhost = 'MONGODB_HOST',
    	dbport = 'MONGODB_PORT',
    	dbname = 'MONGODB_NAME';
    		
    module.exports.open = function() {
    
    	if(mongoose.connection.readyState === 0) {
    
    		var connectionString = "mongodb://";
    		if((typeof(dbuser) === 'string' && dbuser !== '') && (typeof(dbpass) === 'string' && dbpass !== '')) {
    			connectionString += dbuser + ":" + dbpass + "@"; 
    		}
    		connectionString += dbhost + ":" + dbport + "/" + dbname + "?authSource=" + dbname;
    
    		mongoose.connect(connectionString);
    		mongoose.connection.once('open', function() {});
    
    	}
    	
    };
    
    module.exports.connect = function(done) {
    	
    	if(mongoose.connection.readyState === 0) {
    		mongoose.connection.on('error', function(done) {
    			done.call(new Error('database connection error'));
    		});
    	}
    	
    	if(mongoose.connection.readyState === 1) {	
    		done.call();
    	}
    	
    };
    
    

    This will have two methods open() which starts the database connection and connect(function(){}) which handles multiple calls to retrieve, update, create and delete data to/from the database.

    open() and connect(function(){}) methods both use mongoose’s readyState to check whether it should carry out its functions. If disconnected open() method starts the connection, if a connection exists connect(function(){}) handles any calls to the database.

    The nice thing about this is connect(function(){}) also check if a connection exists and allows you send a message to the web client that there is “no connection”

    server.js

    
    
    var db = require('./db'),
        express = require('express'),
        bodyParser = require('body-parser'), 
        app = express();
    
        app.use(bodyParser.urlencoded({ extended: false }));
        app.use(bodyParser.json());	
    
        db.open();
    
    app.get('/api/path-to-api', function(req, res, next) {
    
    	db.connect(function(err) {	
    		if(err) {
    			res.json({ errors: [{ message: 'could not connect to database' }] });
    		} else {
                      	// use your schema models here!
    		}
    	));
    		
    });
    
    

    Mongoose readyState

    Mongoose Connection has a couple of readyState associated with mongoose current state of connection in relation to the database, these include:

    mongoose.connection.readyState === 0 (disconnected)
    mongoose.connection.readyState === 1 (connected)
    mongoose.connection.readyState === 2 (connecting)
    mongoose.connection.readyState === 3 (disconnecting)

    Mongoose Events

    Mongoose also has a number of events you can use to either change its current state or attach extra functionalities to its current state. These events include:

    
    
    mongoose.connection.once('open', function() {
    	console.log('open connection'); 
    });
    
    mongoose.connection.on('connected', function () {  
    	console.log('connection open');
    }); 
    
    mongoose.connection.on('error',function (err) {  
    	console.log('connection error: ' + err);
    }); 
    
    mongoose.connection.on('disconnected', function () {  
    	console.log('connection disconnected'); 
    });
    
    process.on('SIGINT', function() {  
    	mongoose.connection.close(function () { 
    		console.log('connection disconnected through app termination'); 
    		process.exit(0); 
    	}); 
    }); 
    

    For my connection in db.js be careful how you choose to use the events, you can get a memory leak if you get to attach an event more the once.


  2. About Emeka Echeruo

    Emeka Echeruo

    I love sports, football which I refuse to call soccer, and the outdoor especially walks in park. Software development is my passion, there is a beauty in creating something out of nothing but algebra that ends up becomes a part of a persons daily life. I love kids, dogs, nightlife and art because it finds you and moves you emotionally!

  3. Leave a Reply

    Your email address will not be published. Required fields are marked *

    This site uses Akismet to reduce spam. Learn how your comment data is processed.