Olumide
Olumide

Reputation: 31

TypeError: Cannot read property 'db' of null

I am having issue connecting to mongodb atlas, getting the error below

let express = require('express')
let mongodb = require('mongodb')
let app = express()
let db

let connectionString = 'mongodb+srv://olumide:[email protected]/todoApp?retryWrites=true&w=majority'
mongodb.connect(connectionString, {useNewUrlParser: true, useUnifiedTopology: true}, function(err, client){
    db = client.db()
    app.listen(3000)
})

app.use(express.urlencoded({extended: false}))

app.post('/create-item', function(req,res){
   db.collection('item').insertOne({text: req.body.item}, function(){
    res.send("thanks for submitting the form")
   })

})

Error message

Upvotes: 1

Views: 1489

Answers (3)

Kush Kapadia
Kush Kapadia

Reputation: 63

I figured out, in newer versions of MongoDB (3 and higher) they have essentially changed the way of connecting node server to the database. To establish a reusable connection (So that we can access the connected database from any other file), I created an async function in my db.js file where the connection is established and then exported it. In the end of the file, I have called the function. The code is as follows:

const {MongoClient} = require('mongodb')


const client = new MongoClient('mongodb+srv://todoAppUser:<password>@cluster0.6lvjr.mongodb.net/myDatabase?retryWrites=true&w=majority')

async function start(){
  await client.connect()
  console.log("Connected")
  module.exports = client.db()
  const app = require('./app')
  app.listen(3000)
}

  start()

and while calling it from another file:

const productCollection = require('./db').collection("product");

This code gives me no error and works perfectly fine. With the help of the above code, one can use this conveniently while following the MVC (Model-View-Controller) framework.

Upvotes: 1

mohammad Naimi
mohammad Naimi

Reputation: 2359

use mongoose connection as a different javascript file and import it to express script file database.js

let mongoose = require('mongoose');
const server = '127.0.0.1:27017'; // REPLACE WITH YOUR DB SERVER
const database = 'test';      // REPLACE WITH YOUR DB NAME
class Database {
    constructor() {
      this._connect()
    }
    
  _connect() {
       mongoose.connect(`mongodb://${server}/${database}`,{ useUnifiedTopology: true ,useNewUrlParser: true, useFindAndModify: false})
         .then(() => {
           console.log('Database connection successful')
         })
         .catch(err => {
           console.error('Database connection error')
         })
    }
  }
  
  module.exports = new Database()

strong text

Upvotes: 0

mprather
mprather

Reputation: 170

This is because the mongo.connect function is asynchronous. You will need to include the app.post function inside of the mongo.connect callback.

Something kind of like this should work:

let express = require('express')
let mongodb = require('mongodb')
let app = express()

app.use(express.urlencoded({extended: false}))

let connectionString = 'mongodb+srv://olumide:[email protected]/todoApp?retryWrites=true&w=majority'
mongodb.connect(connectionString, {useNewUrlParser: true, useUnifiedTopology: true}, function(err, client){
    const db = client.db()

    app.post('/create-item', function(req,res){
       db.collection('item').insertOne({text: req.body.item}, function(){
        res.send("thanks for submitting the form")
       })
    })

    app.listen(3000)
})

Upvotes: 1

Related Questions