He estado tratando de hacer una aplicación web usando node.js y express y decidí trabajar con mongodb. Estoy usando la versión del controlador mongodb node.js: 4.3.1 He intentado todas las formas posibles de conectar el servidor node.js con mi base de datos mongodb atlas.
Mi base de datos también se conectó usando el siguiente código en mi archivo db.js:
const app = require('./app'); const MongoClient = require('mongodb').MongoClient const Url = 'mongodb+srv://todoAppUser:<myOriginalPasswordHere>@cluster0.6lvjr.mongodb.net/myDatabase?retryWrites=true&w=majority'; MongoClient.connect(Url, function (err, client) { if (err) throw err; var db = client.db('myDatabase'); db.collection('products').findOne({}, function (findErr, result) { if (findErr) throw findErr; console.log(result.name); client.close(); }); });El código anterior funciona bien y también da la salida. Pero quiero usar el marco MVC (Model-view-Controller) para el cual necesito exportar la conexión.
Hice el siguiente cambio en el código anterior:
MongoClient.connect(Url, function (err, client) { if (err) throw err; var db = client.db('myDatabase'); db.collection('products').findOne({}, function (findErr, result) { if (findErr) throw findErr; console.log(result.name); module.exports = db client.close(); }); }); Después del cambio cuando trato de acceder a mi conexión ( const productCollection = require('./db').collection("product"); ) desde cualquier otro archivo mío, me da el siguiente error:
const productCollection = require('./db').collection("product"); ^ TypeError: require(...).collection is not a function at Object.<anonymous> (D:\Kush- Complete Data\exp-projects\nodeApp\productController.js:1:43) at Module._compile (internal/modules/cjs/loader.js:1072:14) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10) at Module.load (internal/modules/cjs/loader.js:937:32) at Function.Module._load (internal/modules/cjs/loader.js:778:12) at Module.require (internal/modules/cjs/loader.js:961:19) at require (internal/modules/cjs/helpers.js:92:18) at Object.<anonymous> (D:\Kush- Complete Data\exp-projects\nodeApp\router.js:3:27) at Module._compile (internal/modules/cjs/loader.js:1072:14) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10) [nodemon] app crashed - waiting for file changes before starting...Que alguien me guíe y me muestre una posible salida.
Gracias, kush
[SOLUCIONADO] Descubrí que, en las versiones más nuevas de mongodb, esencialmente han cambiado la forma de conectar el servidor del nodo a la base de datos. Para establecer una conexión reutilizable (para que podamos acceder a la base de datos conectada desde cualquier otro archivo), creé una función asíncrona en mi archivo db.js donde se establece la conexión y luego la exporté. Al final del archivo, he llamado a la función. El código es el siguiente:
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()y al llamarlo desde otro archivo:
const productCollection = require('./db').collection("product");Este código no me da ningún error y funciona perfectamente bien. Con la ayuda del código anterior, uno puede usar esto convenientemente mientras sigue el marco MVC (Modelo-Vista-Controlador).
Esto no puede funcionar, porque los módulos se evalúan sincrónicamente. Su devolución de llamada se llama de forma asíncrona, pero su módulo ya se evaluó en este momento. Significa module.exports no tiene efecto y require('./db').collection() no está definido. Consulte Módulos de Node.js para obtener más información.
Para resolver su problema, maneje la conexión almacenada en una variable interna del módulo y exporte un getter en lugar de la variable de conexión en sí.
// db.js let client; let db; function connectDB(url, dbName) { client = new MongoClient(url); return new Promise(function(resolve, reject) { client.connect(function(err) { if(err) return reject(err); db = client.db(dbName); return resolve(db); }); }); } function getCurrentDB() { return db; } module.exports.connectDB = connectDB; module.exports.getCurrentDB = getCurrentDB;Luego reutilice su conexión abierta en otros archivos como el siguiente:
// other.js const db = require("./db.js"); db.getCurrentDB().collection("product"); Por supuesto, getCurrentDB() solo puede devolver una conexión a la base de datos si se ha establecido una conexión a través connectDB() antemano. Así que hay que esperar la resolución de la Promesa .