MongoDB and NodeJS cannot create collection

Viewed 51

So I used this exact code about 8 months ago and it worked fine, now suddenly this way of setup does not seem to work. I cannot manage to find what is wrong here and it seems the database just is not connecting at all. Is there a better way to go about this?

'use strict'

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

const url = 'mongodb://toor:root@mongodbdatabase:27017/'

const app = express();
const PORT = 8080;
const HOST = '0.0.0.0';

let con;
MongoClient.connect(url, (err, db) => {
    con = db.db("mongodbdatabase");
})

app.use('/', express.static('public'));

app.get('/createDatabase', (req, res) => {
    con.createCollection("HiveDB", function(err, result) {
        if (err) throw err;
        console.log("Collection Created")
    })
    res.send();
})

console.log(`Listening on port ${PORT}`)

app.listen(PORT, HOST);

Here is the error that I am getting when navigating to localhost:83/createDatabase

TypeError: Cannot read properties of undefined (reading 'createCollection')
    at /usr/src/app/server.js:28:9
    at Layer.handle [as handle_request] (/usr/src/app/node_modules/express/lib/router/layer.js:95:5)
    at next (/usr/src/app/node_modules/express/lib/router/route.js:144:13)
    at Route.dispatch (/usr/src/app/node_modules/express/lib/router/route.js:114:3)
    at Layer.handle [as handle_request] (/usr/src/app/node_modules/express/lib/router/layer.js:95:5)
    at /usr/src/app/node_modules/express/lib/router/index.js:284:15
    at Function.process_params (/usr/src/app/node_modules/express/lib/router/index.js:346:12)
    at next (/usr/src/app/node_modules/express/lib/router/index.js:280:10)
    at SendStream.error (/usr/src/app/node_modules/serve-static/index.js:121:7)
    at SendStream.emit (node:events:537:28)

Im running with docker compose as well

Dockerfile:

FROM node:latest

EXPOSE 8080

WORKDIR /usr/src/app

RUN npm install express --save
RUN npm install mongodb --save
RUN npm install -g loadtest --save

COPY server.js /usr/src/app/server.js
COPY /public /usr/src/app/public


CMD ["node", "server.js"]

docker-compose.yml:

version: '3'
services:

  mainserver:
    build: ./main
    depends_on:
      - mongodbdatabase
    container_name: mainServer
    ports:
      - "83:8080"


  mongodbdatabase:
    image: mongo
    container_name: monDataBase
    ports:
      - 27017:27017
    environment:
      MONGO_INITDB_ROOT_USERNAME: toor
      MONGO_INITDB_ROOT_PASSWORD: root

1 Answers

I will direct you to the relevant documentation from the mongodb client github readme here

In the code snippet you have pasted, you set the con variable with the MongoClient connection but what if the connection fails (and err is provided) ? So the assignment to con probably failed and thats the reason it is undefined in the context of the router.

I would recommend to copy & paste the example from the link i provided.

Using the async/await syntax you can provide the mongodb client to the route handler.

And here is a code snippet using your example:

'use strict'

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

const url = 'mongodb://toor:root@mongodbdatabase:27017/'

const app = express();
const PORT = 8080;
const HOST = '0.0.0.0';

async function init() {
   try{
     const client = await new MongoClient(url).connect()
   }catch(err) {
     console.error(err.message)
   }
   const db = client.db("HiveDB")
   app.use('/', express.static('public'));

   app.get('/createDatabase', (req, res) => {
     db.createCollection("HiveDB", function(err, result) {
          if (err) throw err;
          console.log("Collection Created")
     })
     res.send();
   })

   

   app.listen(PORT, HOST,()=>{
   console.log(`Listening on port ${PORT}`)
   });
}
init()
Related