I want to connect mongodb to nodejs.
I succeed to connect mongodb to nodejs but I can't access to mongodb Collection (test collection).
How can I use collection in my code?
BELOW MY CODE
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/test';
var db;
MongoClient.connect(url, function (err, database) {
if (err) {
console.error('MongoDB 연결 실패', err);
return;
}else{
console.log("DB연결 성공")
}
db = database;
});
var movies = db.Collection('test');
movies.insert();
ERROR CODE
TypeError: Cannot read properties of undefined (reading 'Collection')
at Object.<anonymous> (C:\Users\USER\Desktop\test\mongodbtest.js:15:17)
at Module._compile (node:internal/modules/cjs/loader:1126:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1180:10)
at Module.load (node:internal/modules/cjs/loader:1004:32)
at Function.Module._load (node:internal/modules/cjs/loader:839:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
You are trying to access the db instance sequentially, but the code in the callback will be executed after the var movies = db.Collection('test'); line is called, so the variable won't be set.
You can either move the insert inside the callback:
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/test';
MongoClient.connect(url, function (err, database) {
if (err) {
console.error('MongoDB 연결 실패', err);
return;
} else {
console.log('DB연결 성공');
}
var movies = database.Collection('test');
movies.insert();
});
Or use async await:
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/test';
const connectDb = async () => {
try {
return await MongoClient.connect(url)
} catch (err) {
console.error('MongoDB 연결 실패', err);
}
}
connectDb()
.then((db) => {
var movies = db.Collection('test');
movies.insert();
})
Related
So, I'm trying to connect a mongo database and it's already connected. But my issue is that I can't read collection from mongo in another file, it says: db.collection is not a function.
So this is my db.js file:
const { MongoClient } = require('mongodb');
let connection_string = 'mongodb+srv://username:password#cluster0.3ctoa.mongodb.net/myFirstDatabase?retryWrites=true&w=majority';
let client = new MongoClient(connection_string, {
useNewUrlParser: true,
useUnifiedTopology: true
});
let db = null
export default () => {
return new Promise((resolve, reject) =>{
if (db && client.isConnected()){
resolve(db)
}
client.connect(err => {
if(err){
reject("Error in connection " + err)
}
else{
console.log("Success")
db = client.db("posts")
resolve(db)
coll = db.collection('posts');
}
});
})
};
The thing is I got successfully connected to a database, but when I try to work with collections it says they are not functions.
This is my second file where I already imported connect from db.js, so here is what I want to do:
app.post('/posts', async (req,res)=>{
let db = connect();
let posts = req.body;
let result = await db.collection('posts').insertOne(posts);
})
Here is the exact error I'm getting:
UnhandledPromiseRejectionWarning: TypeError: db.collection is not a function
at _callee$ (C:\Users\Jan\Desktop\Webshop\posts\src\/index.js:21:33)
at tryCatch (C:\Users\Jan\Desktop\Webshop\posts\node_modules\regenerator-runtime\runtime.js:63:40)
at Generator.invoke [as _invoke] (C:\Users\Jan\Desktop\Webshop\posts\node_modules\regenerator-runtime\runtime.js:294:22)
at Generator.next (C:\Users\Jan\Desktop\Webshop\posts\node_modules\regenerator-runtime\runtime.js:119:21)
at asyncGeneratorStep (C:\Users\Jan\Desktop\Webshop\posts\src\index.js:11:103)
at _next (C:\Users\Jan\Desktop\Webshop\posts\src\index.js:13:194)
at C:\Users\Jan\Desktop\Webshop\posts\src\index.js:13:364
at new Promise (<anonymous>)
at C:\Users\Jan\Desktop\Webshop\posts\src\index.js:13:97
at C:\Users\Jan\Desktop\Webshop\posts\src\/index.js:16:1
I followed a tutorial to learn Express.js App that performs basic CRUD operations from MongoDB. All operations created locally works fine.
As a next step (not in the tutorial), I needed to integrate mLab provided by Heroku for MongoDB in order to push the app to Heroku.
Now, I need to make necessary changes on the mongoose connection since I am moving from a local database to mLab. I made necessary changes but now the app throws an error.
complaintController.js (class to get request and use the model)
Complaint = require('./complaintModel');
exports.index = function (req, res) {
Complaint.get(function (err, complaints) { //GET function
if (err) {
res.json({
status: "error",
message: err,
});
}
res.json({
status: 200,
message: "Complaints retrieved successfully",
data: complaints
});
});
};
complaintModel.js (local MongoDB this works fine)
var mongoose = require('mongoose');
var complaintSchema = mongoose.Schema({
name: {
type: String,
required: true
},
});
// Export Complaint model
var Complaint = module.exports = mongoose.model('complaint', complaintSchema);
module.exports.get = function (callback, limit) {
Complaint.find(callback).limit(limit);
}
complaintModel.js ( connecting to mLab throws error)
var mongoDB = "MongoDB URI";
var connection = mongoose.createConnection(mongoDB,
{
User: 'username',
Password: 'pass'
});
var Complaint;
connection.on('open', function() {
console.log('connection established!!!');
Complaint = module.exports = connection.model('master_complaint', complaintSchema);
module.exports.get = function (callback, limit) {
Complaint.find(callback).limit(limit);
}
});
Here I get the following error when I give a get request I understood there is an export issue of Complaint Module but any suggestion or idea will be helpful.
TypeError: Complaint.get is not a function
at exports.index (R:\Workings\PersWork\web\webpack-demo\controller\complaintController.js:6:15)
at Layer.handle [as handle_request] (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\layer.js:95:5)
at next (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\layer.js:95:5)
at R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:281:22
at Function.process_params (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:335:12)
at next (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:275:10)
at Function.handle (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:174:3)
at router (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:317:13)
at R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:284:7
at Function.process_params (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:335:12)
at next (R:\Workings\PersWork\web\webpack-demo\node_modules\express\lib\router\index.js:275:10)
at jsonParser (R:\Workings\PersWork\web\webpack-demo\node_modules\body-parser\lib\types\json.js:110:7)
From what I can see in the code. complaintController will be used by the express.js router, Am I correct?
I also see in the complaintModel.js is that the get function you've exported requires 2 parameters which are a filter & a limit. But in the Controller file you're not providing any of those arguments at all.
I haven't tested this myself yet but try changing your complaintModel.js to this
var mongoose = require("mongoose");
var complaintSchema = mongoose.Schema({
name: {
type: String,
required: true
}
});
var Complaint = mongoose.model("master_complaint", complaintSchema);
// Exports the get function
module.exports.get = function(filter, limit, callback) {
var mongoDB = "MongoDB URI";
var connection = mongoose.createConnection(mongoDB, {
User: "username",
Password: "pass"
});
connection.on("open", function() {
console.log("connection established!!!");
Complaint.find(filter)
.limit(limit)
.exec()
.then(results => {
callback(undefined, results)
})
.catch(err => {
console.log(err);
callback("ERROR: Can't query the collection", undefined)
});
});
};
And change the complaintController.js to the following
var Complaint = require("./complaintModel");
module.exports.index = function(req, res) {
var params = req.query;
const filter = params.filter;
const limit = params.limit;
Complaint.get(
filter,
limit,
(err,
complaints => {
if (err) {
res.json({
status: "error",
message: err
});
} else {
res.json({
status: 200,
message: "Complaints retrieved successfully",
data: complaints
});
}
})
);
};
This is connection.js
var MongoClient = require('mongodb').MongoClient;
var db_singleton = null;
var getConnection= function getConnection(callback) {
if (db_singleton) {
callback(null,db_singleton);
} else {
var connURL = "mongodb://localhost:27017/testdb";
MongoClient.connect(connURL,function(err,db){
if(err)
console.log("Error creating new connection "+err);
else
{
db_singleton=db;
console.log("created new connection");
}
callback(err,db_singleton);
});
}
};
module.exports = getConnection;
And this is product.js
var getConnection = require('../../connection.js');
var products = null;
getConnection(function(err,db) {
var collection = db.collection("products");
collection.find().toArray(function(err, productsDB) {
products = productsDB;
})
});
console.log(products);
module.export = products;
console.log(products) is always null.
But it should be object.I would like to cache variable when server starts.
I use mongodb and in mongodb I put my username and password.
The code is:
var mongodb = require('mongodb');
var http = require('http');
var fs=require('fs');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser());
app.listen(8080, function() {
console.log('Server running at http://127.0.0.1:8080/');
});
app.post('/prova', function(req, res) {
// res.send('You sent the name "' + req.body.username + '".');
var MongoClient = mongodb.MongoClient;
// Connection URL. This is where your mongodb server is running.
var url = 'mongodb://localhost:27017/utente';
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
//HURRAY!! We are connected. :)
console.log('Connection established to', url);
var collection = db.collection('login');
// var prova1=({name:"documento1",url:"sadsad",tag:"dc1"});
// do some work here with the database.
var cursor = collection.find();
cursor.each(function (err, doc) {
if (err) {
console.log(err);
} else {
// console.log('Fetched:', doc);
var username=0;
var password=0;
for(valore in doc){
if(valore!="_id"){
if(valore=="username"){
if(doc[valore]==req.body.username){
username=1;
}
}
if(valore=="password"){
if(doc[valore]==req.body.password){
password=1;
}
}
}
}
if(username==1 && password==1){
console.log("entra");
// res.end();
}else{
fs.readFile('C:\\Users\\Eventi\\Desktop\\Node.js\\Progetti\\ProveNodeJS\\NodeJSProve\\paginaRifiuto.html', function (err, html) {
if (err) {
}
res.writeHeader(200, {"Content-Type": "text/html"});
res.write(html);
res.end(html);
});
}
}
});
//Close connection
}
});
});
http.createServer(function(request, response) {
fs.readFile('C:\\Users\\Eventi\\Desktop\\Node.js\\Progetti\\ProveNodeJS\\NodeJSProve\\home.html', function (err, html) {
if (err) {
}
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
response.end();
});
}).listen(8000);
I call first http://localhost:8000 and I put in a text field the wrong value of username and password and after I click login I see my "login fail page" but I obtain this error:
Connection established to mongodb://localhost:27017/utente
_http_outgoing.js:335
throw new Error('Can\'t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.writeHead (_http_server.js:195:21)
at ServerResponse.writeHeader (_http_server.js:233:18)
at C:\Users\Eventi\Desktop\Node.js\Progetti\ProveNodeJS\NodeJSProve\HelloWord.js:67:23
at fs.js:334:14
at FSReqWrap.oncomplete (fs.js:95:15)
I want build a class for wrapping database connection. This is my code ('db.js' file):
var mongodb = require('mongodb');
var Class = function() {
this.db = null;
var server = new mongodb.Server('127.0.0.1', 27017, {auto_reconnect: true});
db = new mongodb.Db('myDB', server);
db.open(function(error, db) {
if (error) {
console.log('Error ' + error);
} else {
console.log('Connected to db.');
this.db = db;
}
});
};
module.exports = Class;
Class.prototype = {
getCollection: function(coll_name) {
this.db.collection(coll_name, function(error, c){ // <--- see error below
return c;
});
}
}
exports.oid = mongodb.ObjectID;
Then, my test code ('test.js' file):
var DB = require('./db');
var myDB = new DB();
myDB.getCollection('myCollection'); // <--- error: Cannot call method 'collection' of null
You are missing "this" in front of "db". eg:
this.db = new mongodb.Db('myDB', server);
And the line next to it.