1

I have implemented the following code from this link:

What is best way to handle global connection of Mongodb in NodeJs

to create a class for the connection of MongoDB. But when I try to call the singleton class in the router, I get the following error:

TypeError: Connection.db.collection is not a function

mongodb.js

const MongoClient = require('mongodb').MongoClient
const url = '...';

class Connection {
    static connectToDB() {
        if ( this.database ) return Promise.resolve(this.database)
        return MongoClient.connect(this.url, {useNewUrlParser: true}, (err, db) => {
            if (err) console.log(err);
            else {
                this.db = db;
                console.log('MongoDB connected');
            }
        })
    }
}

Connection.db = null
Connection.url = url
Connection.options = {
    bufferMaxEntries:   0,
    reconnectTries:     5000,
}

module.exports = Connection;

app.js

const express = require('express');
const app = express();
let bodyParser = require('body-parser')

// mongodb config
const Connection = require('../config/mongodb');

const server = app.listen(3000, () => {
    Connection.connectToDB(); // output: MongoDB connected
    console.log(`listening to port: ${port} on http://127.0.0.1:3000}/`); // output: listening to port: 3000 on http://127.0.0.1:3000/
});

router.js

const router = require('express').Router();
let Connection = require('../config/mongodb');

router.post('/data', (req, res) => {
    Connection.db.collection('tweets').find({}) // output: TypeError: Connection.db.collection is not a function
        .then(tweets => console.log(tweets))
        .catch(err => console.log(err));
});
omaq
  • 27
  • 5
  • Try once to package.json, change mongodb line to "mongodb": "^2.2.33". You will need to npm uninstall mongodb; then npm install to install this version. – Jitendra Oct 21 '18 at 16:11

2 Answers2

0

The question you linked uses promises throughout, whereas you're using the callback version of connect.

return MongoClient.connect(this.url, {useNewUrlParser: true}, (err, db) => ...

You then call this without returning in your server:

Connection.connectToDB();
console.log(`listening to port: ${port} on http://127.0.0.1:3000}/`);

There is therefore no guarantee that your connection will have been made by the time your first api request comes in. In fact, if you did:

Connection.connectToDB();
console.log(`listening to port: ${port} on http://127.0.0.1:3000}/`);
Connection.db.collection('tweets').find({});

It would fail every time as Connection.db will still be null.

In the example you linked, using Promises protect against that. Note in particular the connect method:

static connectToDB() {
    if ( this.database ) return Promise.resolve(this.database)
    // ** USING THE PROMISE VERSION OF CONNECT **
    return MongoClient.connect(this.url, this.options)
        .then(db => this.db = db)
}

and your usage code should also use promises:

return Connection.connectToDB()
    .then(() => {
        // do something here
    });
sofcal
  • 490
  • 3
  • 7
0

Try once to package.json, change mongodb line to "mongodb": "^2.2.33". You will need to npm uninstall mongodb; then npm install to install this version.

Jitendra
  • 3,135
  • 2
  • 26
  • 42