access collection in mongodb through native driver - node.js

I have set up a mongo database and have successfully connected through the native driver like so:
var mongo=require('mongodb').MongoClient;
var db;
mongo.connect('mongodb://path/to/db',function(err,db1){
if(err){
console.log(err);
}else{
console.log('mongo connection established');
db=db1;
}
});
I then try to update a preexisting collection:
if(db){db.test.save({hello:'world'});}
I get an error saying cannot call save of undefined.

Try using the following syntax:
db.collection('test').save({hello:'world'}, callback);
In Node.js you need to use the collection method to access the collection (which is different from the MongoDB shell)

Related

TypeError: Cannot read property 'db' of undefined. when using mongodb atlas but no error when using mongodb locally

i get the error when i use the mongodb atlas but when using the mongodb locally(mongo installed on my computer) the code runs very well with no errors.
http.listen(3000, function(){
console.log("Server started");
mongoClient.connect("mongodb+srv://<username>:<password>#myname.anjzd.mongodb.net/<dbname>?retryWrites=true&w=majority", function(error, client){
var database = client.db("mydatabase");
console.log("Database connected.");
});
That's because you've got an error from this callback and therefore your client will be set to null.
I guess the error comes from your URL that you put inside connect.
<username>, <password> and <dbname> are placeholders for your real username, password and database name respectively.
say your real username, password and database are ABC, 123 and myDB respectively, then your connection URL would be something like this:
let url = "mongodb+srv://ABC:123#myname.anjzd.mongodb.net/myDB?retryWrites=true&w=majority"
If the error is caused by something else you can handle it properly to detect the reason.
mongoClient.connect(url, function(error, client){
if (error) return console.log(error);
var database = client.db("mydatabase");
console.log("Database connected.");
});

I'm stuck trying to post data from client to mongodb

I’m trying to pass data from my server app.js to my database file so that I can store it into MongoDB atlas.
I can see where the problem is I'm honestly just not sure how to go about fixing it. The problem seems to be two parts.
1.) I'm passing a function into .insertOne and not an object, this is resulting in a promise error. When I try to change things in the userDataFinal function I start running into scope errors and things not being defined. I'm not really sure how to fix this.
2.) my code is trying to create a new document as soon as it starts up because
db.collection('User').insertOne(userDataFinal);
is located in the .connect callback function.
I need this code to run only when a put request has been made on the client side.
relevant server code app.js
const base = require('./base.js');
app.post('/',(req, res)=>{
var userName = req.body;
base.userDataFinal(userName);
res.render('index');
});
Relevant database code base.js
var userDataFinal = function getUserName(user){
console.log(user);
}
module.exports = {userDataFinal};
////////////////////////////////////////////////////////////////////////
// connects to the database
MongoClient.connect(URL, {useNewUrlParser: true}, (error, client)=>{
if(error){
return console.log('Could not connect to the database');
}
// creates a new collection
const db = client.db(database);
// adds a document to the designated collection
db.collection('User').insertOne(userDataFinal);
console.log('Database is connected...')
});
First, you are passing a callback into your MongoClient.connect() function.
This callback is useful when you want to make sure that you are connected.
As you said it, you want your code to run only when the request has been made. You can remove your insertion from the connect, but you can still keep the error handling part as it is always useful to know why there was a db connection error.
Also, you are calling the mongo insertOne method, that expects an object. You are passing it a function.
EDIT: Create a db variable outside all your functions, then assign it from the Mongo connect callback once you have access to the client.
You will be able to use this db later in the routes.
var MongoClient = require('mongodb').MongoClient;
var db; // Will be set once connected
MongoClient.connect(URL, {useNewUrlParser: true}, (error, client)=>{
if(error){
return console.log('Could not connect to the database');
}
db = client.db(database);
console.log('Database is connected...')
});
app.post('/',(req, res)=>{
var userName = req.body.username;
db.collection('User').insertOne({ username: userName });
res.render('index');
});
Please note that you are probably passing the userName through the body, in this case you need to retrieve it that way: req.body.username (if you named the related body parameter username).

db.createCollection is not a function

I am attempting to create a mongo instance however I am unable to access any of the helper methods from the mongodb nodejs driver.
My mongo instance is running within docker and the ports have been opened up to my local.
TypeError: db.createCollection is not a function
at /var/www/html/beacon/index.js:6:8
at args.push (/var/www/html/beacon/node_modules/mongodb/lib/utils.js:431:72)
at /var/www/html/beacon/node_modules/mongodb/lib/mongo_client.js:254:5
at connectCallback (/var/www/html/beacon/node_modules/mongodb/lib/mongo_client.js:933:5)
at /var/www/html/beacon/node_modules/mongodb/lib/mongo_client.js:794:11
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickCallback (internal/process/next_tick.js:104:9)
Copied from w3schools...
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/mydb";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
db.createCollection("customers", function(err, res) {
if (err) throw err;
console.log("Collection created!");
db.close();
});
});
No error is returned through the run, and no methods are exposed on the db object.
any ideas?
According to the changelog for Mongodb 3.0 you now get a client object containing the database object instead:
So you need the db object that points to the database you want to use, in your case mydb. Try this:
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) { //here db is the client obj
if (err) throw err;
var dbase = db.db("mydb"); //here
dbase.createCollection("customers", function(err, res) {
if (err) throw err;
console.log("Collection created!");
db.close(); //close method has also been moved to client obj
});
});
You're not the one facing this issue. Seems that 3.0 mongo driver has a bug or these are just breaking backwards compatibility changes. Take a look here:
db.collection is not a function when using MongoClient v3.0
To use DB name in the URL, you need to uninstall MongoDB, change to "mongodb": "^2.2.33" in dependencies and do npm install to install the new version.
Or you can install specific version with command npm install mongodb#2.2.33 --save
I was getting the error while running createCollection() from the command line Mongo shell tool mongosh.
TypeError: db.createCollection is not a function
In my case, I could not get create collection to work, so I resorted to just inserting a document into the collection which I wanted to create. By default, Mongo will create a collection by that name on the fly, assuming you have the permissions to do so. This is not an ideal solution, but it allowed me to proceed at least.

Does mongodb require connection on each operation

So i am very new to mongodb and i wish to use it in my application. Now i HATE redundant code but reading up on how to use mongodb with node.js it seems that there is a pattern where you always have to connect before making any CRUD operation.
Example from the offical documentation:
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
insertDocument(db, function() {
db.close();
});
});
My question is. is it possible to make a middleware that keeps the connection open so you only has to call insertDocument (in the above example) ?
Yea of course, just keep the db variable around until you don't need it any longer - then call close()
var mdb;
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
mdb = db;
insertDocument(mdb, function() {
// ...
});
});
// do other stuff with mdb
You can also look into using Mongoose as you mentioned middleware.
The connection is only opened once (on the global scope) and then you can use it throughout the app.

How to init native Mongo in NodeJS with at Sign in password

I am trying to figure out how to connect to my mongodb db using the native node mongo driver and I have two issues:
My password contains an # sign making it break the normal user:pass#host connection string format
How do I list databases from what I have below?
Any ideas on how to address this?
Here is an attempt which does not work:
var Mongo = require('mongodb');
var server = new Mongo.Server('mongodb://myhost', 27017);
var db = new Mongo.Db('test', server);
db.open(function(err, db) {
console.log(err); //unable to connect
});
For future readers, I was able to resolve this with the connection option uri_decode_auth. You will need to encodeURIComponent(password) before embedding it in the connection string.
Here's a complete working example:
MongoClient.connect(connection, { uri_decode_auth: true }, function(err, db) {
if(err) {
return cb(err);
}
db.admin().listDatabases(function(err, dbs) {
console.log(dbs);
});
});
As mentioned on this answer:
The solution is to replace # with %40
I tested with the C# driver and it works like a charm.

Resources