Export from MongoClient.connect() is not being read in other module

In my controller /src/controllers/ordersController

import OrdersDAO from '../dao/ordersDAO.js'

export default class OrdersController {
  static async apiGetOrders(req, res, next) {
    try {
      console.log('OrdersController  ~~~ made it to the controller step 1')
      const orders = await OrdersDAO.getOrders()
      console.log('line 12 ordersController', orders)
      res.status(200).json(orders)
    } catch (e) {
      console.log(e, 'Bummer Dude')
      return { e }
    }
  }

  static async apiPostOrder(req, res, next) {
    try {
      console.log(req.body, 'line 22 ordersController')
      await OrdersDAO.addOrder(req.body)
      return res.header()
      // res.status(200)
    } catch (error) {}
  }
}

@Kevin_Turney, what is the error you are getting? Can you post a screenshot or content of the error’s stack trace?

see the photo I posted above…

The route is hit, the controller calls getOrders() in OrdersDAO, OrdersDAO.getOrders() fails to read orders.

The following in the screenshot:

line 12 ordersController { TypeError: Cannot read property ‘db’ of undefined…

Where is this property db in the function getOrders?

it’s not in there. When I just console.log(orders) in getOrders(), orders is undefined, still not readable from when injectDB() initialized orders.

Please post the index.js code.

import app from './server.js'
import pkg from 'mongodb'
const { MongoClient } = pkg
import OrdersDAO from '../src/dao/OrdersDAO.js'

const port = process.env.PORT || 8000
const uri = process.env.COOKIE_DB_URI


MongoClient.connect(uri,
  { useNewUrlParser: true, poolSize: 50, useUnifiedTopology: true })
  .catch((err) => {
    console.error(err.stack)
    process.exit(1)
  })
  .then(async (client) => {
    console.log(`Index.js ~~~~ Connecting to database`)
    await OrdersDAO.injectDB(client)
    app.listen(port, () => {
      console.log(`listening on port ${port}`)
    })
  })

Hi @Kevin_Turney, it is difficult to tell where the issue is with what I am seeing. But, can you verify the OrdersDAO class and see where all the field orders is used? By chance, is it redefined (or reassigned somewhere)?

Here is the entire file for OrdersDAO

let orders

export default class OrdersDAO {
  static async injectDB(clientConnection) {
    if (orders) {
      return
    }
    try {
      orders = await clientConnection
        .db(process.env.COLLECTION_DB)
        .collection('orders')
      console.log('OrdersDAO ~~~ line 22 ordersDAO connecting....', orders)

      let cursor = await orders.find({})
      let allOrders = await cursor.toArray()
      console.log(`OrdersDAO ~~~ line 36`, allOrders) // viewing the array of orders in the console

      console.log(`You connected you magnificent bastard!!!`)
      return orders
    } catch (e) {
      console.error(`Unable to establish collection handles in OrdersDAO: ${e}`)
    }
  }

  static async getOrders() {
    let cursor
    try {
      cursor = await orders.find() // orders is still undefined here
      console.log(`OrdersDAO ~~~ 94`, cursor)

    } catch (e) {
      console.error(`OrdersDAO.getOrders() ~~~ Unable to get orders: ${e}`)
      return { e }
    }
  }
}

Thanks. When you start the application are you seeing these messages? If so, please include a screenshot.

OrdersDAO ~~~ line 22 ordersDAO connecting…
OrdersDAO ~~~ line 36
You connected you magnificent bastard!!!

From the screenshot I see the orders is not undefined. It has a value. And, are you seeing the above message?

You can also include the following code in the injectDB method before the return statement.:

this.orders = orders;

I tried that just like in the mflix source, doesn’t do anything except for referencing orders in the test suites.

Orders is not undefined in injectDB, in getOrders() it is. Look closely at the console.log statements.

@Kevin_Turney, can you post the entire error message from the post no. 24 (it is only a partial screenshot)?



and then when the /admin route hits getOrders() is called and

Hi @Kevin_Turney, it is difficult to tell why your code is not working with what is posted. It is a possible that there are different versions of the code and there is some conflict somewhere.

This is unrelated, but you don’t have a return statement in the getOrders method, but, the controller code is showing that you are expecting a return value. Also, there is a return in the injectDB (what is it for?). Are you sure you had posted the same code you are running (please verify again)?

Thanks Prasad, you put a heroic effort in trying to help me. I was experimenting with the return in injectDB, it had no effect. As for the the getOrders(), if I could console.log, then I know I could eventually return what the controller expected. I really wanted to work with node driver, I did not want to use Mongoose, but I may have to if I can’t get this to work by tomorrow.

@Kevin_Turney, you don’t necessarily need to use Mongoose. Instead try the following method:
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.