Error when connecting to mongodb - node.js

I am using node-run-cmd package to start the mongodb server in my app.js file. I know this works because I can see the collections on Robomongo when my script is running as well as the mongod.exe in my list of running processes. The problem is trying to connect to the db called testDB. Below is the commented code.
//start mongodb server
//this works
var nrc = require('node-run-cmd');
var cmd = '..\\mongodb\\mongod --dbpath '+__dirname+'\\db';
nrc.run(cmd);
//setup
var express = require('express');
var MongoClient = require('mongodb').MongoClient;
var app = express();
app.use(express.static('public'));
app.set('view engine', 'ejs');
//connect to mongo
//this fails to connect to db testDB
var url = 'mongodb://localhost:27017/testDB';
MongoClient.connect(url, function(err, db) {
if(!err) {
console.log("connection successful");
}
else{
console.log(err.message)
}
});
Here is the err.message
failed to connect to server [localhost:27017] on first connect
Any idea what I am doing wrong here. My assumption is that the db connection is trying before the server has fully started but I am not completely sure.
EDIT:
so that's what it was, timing issue. I tried the following and it connected to the DB. Is there a graceful way of doing this other than what I have here?
function connect(){
var url = 'mongodb://localhost:27017/testDB';
MongoClient.connect(url, function(err, db) {
if (!err) {
console.log("connection successful");
}
else {
console.log(err.message)
}
});
}
setTimeout(connect, 10000);

You should use the callback in the node_run_cmd package (https://www.npmjs.com/package/node-run-cmd#callback-style).
Place your connect function inside the callback.
You will probably also want to only start express here as well.

Related

Connection to MongoDB server using Node is unresponsive on localhost

I am trying to connect my node.js game to a MongoDB cluster so that I can store username and passwords. I already have the a mock DB stored locally using express + socket.io. I am trying to set up MongoDB atlas to store the usernames + passwords so that when the local host closes, the data won't disappear.
I've tried the following Developing A RESTful API With Node.js And MongoDB Atlas word for word. When I test my connection if it was successful, I enter on terminal:
node app.js
My server starts as expected and prints server started. From this tutorial, I should either see an error or a successful connection message. However, when I start the server, I don't see either. I am having trouble debugging this because I am not getting any response at all.
Here is the beginning of my app.js file for context.
// Express code
var express = require('express');
var app = express();
var serv = require('http').Server(app);
var MongoClient = require('mongodb').MongoClient;
const CONNECTION_URL = *uri here*
const DATABASE_NAME = "bunnyCrossing";
var timeRemaining;
// If query is '/' (nothing)
app.get('/',function(req,res){
res.sendFile(__dirname + '/client/index.html');
});
// If query is '/client'. Client can only request things from client folder
app.use('/client',express.static(__dirname + '/client'));
// replace the uri string with your connection string.
var database, collection;
app.listen(3000, () => {
MongoClient.connect(CONNECTION_URL, { useNewUrlParser: true }, (error, client) => {
if(error) {
throw error;
}
database = client.db(DATABASE_NAME);
collection = database.collection("people");
console.log("Connected to `" + DATABASE_NAME + "`!");
});
});
// Server starts listening on port 2000
serv.listen(2000);
console.log("Server started");
I should see when I run node app.js:
server started
Connected to `bunnyCrossing`!
But I just see:
server started
Either app.listen is not being called or you must hit localhost:3000 to invoke the callback to connect to mongo database.
Either remove serv.listen or add a callback to serv.listen as such and remove app.listen.
serv.listen(2000, function(err) {
if (err) console.log(err);
else {
MongoClient.connect(CONNECTION_URL, { useNewUrlParser: true }, (error, client) => {
if(error) {
throw error;
}
database = client.db(DATABASE_NAME);
collection = database.collection("people");
console.log("Connected to `" + DATABASE_NAME + "`!");
});
}
})

mongojs driver not connecting to mongodb

i have been trying to connect to my local mongodb using mongojs package but its not connecting at all. i have my mongo service running on http://127.0.0.1:27017/ and below is my code :
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mongo= require('mongojs');
var db=mongo('catalog',['products']);
app.use(bodyParser.json);
//adding our first route name
db.on('connect', function () {
console.log('database connected')
})
app.get('/',function(req,res){
res.send('It Worked');
});
app.get('/products',(req,res)=>{
db.products.find(function (err,docs) {
if (err) {
res.json(err)
}else{
res.json(docs)
}
})
});
i have set event on connect to log if the connection is established but nothing is showing up.do you i could use mongoose or some other packages if it doesnt work at all?
mongojs doesn't fire the connect function until you make the first request to a collection. Make a request to your collection and the on('connect') function will fire.
Or in your case go to /products in your browser and you can see the database connected log in your terminal.
If you want to request records from your collection without going to /products in your browser then just write your query outside of your app.get('/products').
Make sure you add
app.listen(3000, function() {
console.log('server is running');
});
at the the end and go to localhost:3000/products in your browser.

Mongoose never returns its promise when I try to connect to the same db using a working URL

I have a locally hosted mongodb that I can connect to using mongodb.MongoClient.
Working code:
var mongoClient = require("mongodb").MongoClient;
...
var startApp = function(db) {
// Get our collections in an easy to use format
var database = {
chats: db.collection('chats'),
messages: db.collection('messages')
};
// Configure our routes
require('./app/routes')(app, database);
// START APP
// Start app on port
app.listen(port);
// Tell user the app is running
console.log("App running on port " + port);
// Expose app
exports = module.exports = app;
}
// DATABASE
var database = null;
mongoClient.connect(config.url, function(err, returnDB) {
if(err) {
console.log(err);
} else {
console.log("DB connected");
startApp(returnDB);
}
});
Legacy code that no longer works:
var mongoose = require('mongoose');
...
// Connect to DB
console.log('Connect to database (' + db.url + ')');
mongoose.connect(db.url);
I have added a callback to this connect method but it never gets called (error or no error, this connect function never gets to my callback).
This entire legacy app relies on the API using mongoose to talk to the database so I do not want to redo it all using mongodb. How can I fix this?
*config.url and db.url are loaded from the same file and it is a valid and running mongodb.
It was really easy to fix. Thanks #Bhavik for asking me what version I was using.
I updated mongoose to 4.8.1 by specifying the newest version in packages.json and the issue is resolved.

How can I connect to mongodb using express without mongoose?

I am using the express framework and would like to connect to a mongodb without using mongoose, but with the native nodejs Mongodb driver. How can I do this without creating a new connection every time?
To handle get or post requests I currently open a new connection to the db for every request and close it on completion of the request. Is there a better way to do this? Thanks in advance.
Following the example from my comment, modifying it so that the app handles errors rather than failing to start the server.
var express = require('express');
var mongodb = require('mongodb');
var app = express();
var MongoClient = require('mongodb').MongoClient;
var dbURL = "mongodb://localhost:27017/integration_test";
var db;
// Initialize connection once
MongoClient.connect(dbURL, function(err, database) {
if(err) return console.error(err);
db = database;
// the Mongo driver recommends starting the server here
// because most apps *should* fail to start if they have no DB.
// If yours is the exception, move the server startup elsewhere.
});
// Reuse database object in request handlers
app.get("/", function(req, res, next) {
var collection = "replicaset_mongo_client_collection";
db.collection(collection).find({}, function(err, docs) {
if(err) return next(err);
docs.each(function(err, doc) {
if(doc) {
console.log(doc);
}
else {
res.end();
}
});
});
});
app.use(function(err, req, res){
// handle error here. For example, logging and
// returning a friendly error page
});
// Starting the app here will work, but some users
// will get errors if the db connection process is slow.
app.listen(3000);
console.log("Listening on port 3000");
var mongodb = require('mongodb');
var uri = 'mongodb://localhost:27017/dbname';
module.exports = function(callback) {
mongodb.MongoClient.connect(uri, callback);
};
Ad this snippet in a file say connect.js and then require this file(connect.js) in your file where you are declaring your functions for http requests.

Setting up mongodb on Heroku with Node

On my local host, I have the following Node code to setup a mongoDB database name "dbname":
users.js:
var MongoClient = require("mongodb").MongoClient,
Connection = require("mongodb").Connection,
Server = require("mongodb").Server;
Users = function(host, port) {
var mongoClient = new MongoClient(new Server(host, port));
mongoClient.open(function (){});
this.db = mongoClient.db("dbname");
};
Users.prototype.getCollection = function (callback) {
this.db.collection("users", function (error, users) {
if (error) callback(error);
else callback(null, users);
});
};
Users.prototype.findAll = function (callback) {
this.getCollection(function (error, users) {
if (error) {
callback(error);
} else {
users.find().toArray(function (error, results) {
if (error) {
callback(error);
} else {
callback(null,results);
}
});
}
});
}
// Bunch of other prototype functions...
exports.Users = Users;
I like to put the above database functionality in one file, and then in my main server file require that file as follows:
server.js:
var Users = require("./users").Users;
var users = new Users("localhost", 27017);
users.findAll(function (err, user) {
// Do something
});
To have this working on localhost is pretty easy. In the command line, I just type the following:
$ mongod # to launch the database server
$ node server.js # to launch the web server
and it works fine. However, now I'm trying to push the whole thing onto Heroku with the mongolab addon
heroku addons:add mongolab
but the database is not running and I have no idea how to make it run. This tutorial explains how to setup mongodb with the mongolab URI, but that's not how my code works, I use a host and a port and I create a new server based on that. How should I change my code for it to work on the heroku app? I want to keep the database code in a separate file, with the prototype functions.
Follow the example here at the "MongoClient.connect" section.
Essentially, you will need to change this part of the code:
Users = function(host, port) {
var mongoClient = new MongoClient(new Server(host, port));
mongoClient.open(function (){});
this.db = mongoClient.db("dbname");
};
To use mongoClient.connect() instead of new MongoClient:
Users = function(url) {
MongoClient.connect(url, function(err, db) {
// Find better way to set this since this callback is asynchronous.
this.db = db;
});
};
If you are using node, I recommend using a library such as mongoose npm install mongoose to handle mongodb interactions. Look at my answer here for how to structure your schemas.
Helped by Xinzz's answer, here's the modified code, so that the mongodb database is initialized with a URI instead of host + port. That's how Heroku initializes the mongodb database, and that's why it wasn't working.
var mongodb = require("mongodb");
var MONGODB_URI = process.env.MONGOLAB_URI || process.env.MONGOHQ_URL || "mongodb://localhost", // Make sure to replace that URI with the one provided by MongoLab
db,
users;
mongodb.MongoClient.connect(MONGODB_URI, function (err, database) {
if (err) throw err;
db = database;
users = db.collection("users");
accounts = db.collection("accounts");
var server = app.listen(process.env.PORT || 3000);
console.log("Express server started on port %s", server.address().port);
});
The key here is to declare the variables db and users upfront, assign them a value in the asynchronous callback of the connect function of MongoClient and also start the app (app.listen(...)) in the same callback. Then later in the code I can do the following:
users.find().toArray(function (err, results) {
// Do something
});
I also gave up on all these prototype functions, since they did not really add much.

Resources