4
votes

Im trying to perform a CRUD op using Node and MongoDB.

Im getting the below error.

TypeError: Cannot read property 'collection' of undefined

const express = require('express')
const bodyParser= require('body-parser')
const MongoClient = require('mongodb').MongoClient
const app = express()
app.use(bodyParser.urlencoded({extended: true}))

const url = 'mongodb://localhost:27017/testdb';

var db
MongoClient.connect(url, function(err, client) {
  if (err) return console.log(err)
  var db = client.db('testdb');

})

app.post('/quotes', (req, res) => {
    var collectionName = 'quotes';
    var collection = db.collection(collectionName);
    collection.save(req.body, (err, result) => {
    if (err) return console.log(err)

    console.log('saved to database')
    res.redirect('/')
  })
})

Error trace:

TypeError: Cannot read property 'collection' of undefined at app.post (/var/www/html/Express/SimpleCrud/server.js:20:21) at Layer.handle [as handle_request] (/var/www/html/Express/SimpleCrud/node_modules/express/lib/router/layer.js:95:5) at next (/var/www/html/Express/SimpleCrud/node_modules/express/lib/router/route.js:137:13) at Route.dispatch (/var/www/html/Express/SimpleCrud/node_modules/express/lib/router/route.js:112:3) at Layer.handle [as handle_request] (/var/www/html/Express/SimpleCrud/node_modules/express/lib/router/layer.js:95:5) at /var/www/html/Express/SimpleCrud/node_modules/express/lib/router/index.js:281:22 at Function.process_params (/var/www/html/Express/SimpleCrud/node_modules/express/lib/router/index.js:335:12) at next (/var/www/html/Express/SimpleCrud/node_modules/express/lib/router/index.js:275:10) at /var/www/html/Express/SimpleCrud/node_modules/body-parser/lib/read.js:130:5 at invokeCallback (/var/www/html/Express/SimpleCrud/node_modules/raw-body/index.js:224:16)

Im using Mongodb 3.1

3

3 Answers

5
votes

Hei there,

Try with: const url = 'mongodb://localhost:27017';

Update: According to mongodb package v3.x, the declaration of the DB is done separately and not as a part of the URL. More info here: https://www.npmjs.com/package/mongodb

4
votes

This is a simple closure issue var is a local/global scope, you have multiple declaration of var db

var db  <====== first declaration which is undefined 
MongoClient.connect(url, function(err, client) {
 if (err) return console.log(err)
 var db = client.db('testdb');   <======= second declaration where u connected to 
 the db which is undefined out of this scope

})

i personally prefer mongoose as long as it's not with typescript :D

several examples:

const MongoClient = require('mongodb').MongoClient,
Server = require('mongodb').Server;

const mongoClient = new MongoClient(new Server('localhost', 27017));
mongoClient.open(function(err, mongoClient) {
const db1 = mongoClient.db("mydb");

mongoClient.close();
});

or

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

// Connection URL
const url = 'mongodb://localhost:27017';

// Database Name
const dbName = 'myproject';

//Use connect method to connect to the server
MongoClient.connect(url, function(err, client) {
  assert.equal(null, err);
  console.log("Connected successfully to server");

  const db = client.db(dbName);

  client.close();
});

source

0
votes

There is simple mistake in the code. You have started the http server before making connection with mongodb server. That's why the variable db was undefined when your post api was loaded in the memory. Since the connection with mongodb is async. In order to utilize the mongodb instance you have to first connect with mongdb server and then starts the http server and store the db instance globally or in some module which you can require and get the db instance to perform queries.