i am trying to display all the documents in a collection called tutorial so i am using a simple code here's my code
const mongodb = require("mongodb");
const express = require("express");
var app = express();
var mongoClient = mongodb.MongoClient;
var conn = "mongodb://localhost:27017";
mongoClient.connect(conn, (err, client) => {
if (err) {
console.log(err);
} else {
console.log("connection estableshed");
var db = client.db("mydb");
var collection = db.collection("tutorial");
collection.find().toArray((err, data) => {
console.log(data);
});
client.close();
}
});
but the result i got undefined so what seems to be the problem here?
Problem with the callback, you can use then() method instead.
const mongodb = require("mongodb");
const express = require("express");
var app = express();
var mongoClient = mongodb.MongoClient;
var conn = "mongodb://localhost:27017";
mongoClient.connect(conn).then((err, client) => {
if (err) {
console.log(err);
} else {
console.log("connection established");
var db = client.db("mydb");
var collection = db.collection("tutorial");
collection
.find()
.toArray()
.then((data) => {
console.log(data);
});
client.close();
}
});
app.listen(3000, () => {
console.log("Server started");
});
Related
Mongo save callback is not triggering, but the document is getting saved in the db, Heres my code:
MongoDb Version : 6.0.1
Mongoose Version : 6.8.2
The call back not returning anything, but the documents are getting saved without any issues, why the call back is not triggering?
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const url = 'mongodb://127.0.0.1:27017/musicapp';
const cors = require('cors');
var jquery = require('jquery');
//Mongodb
mongoose.connect(url, { useNewUrlParser: true });
mongoose.set('strictQuery', true);
var conn = mongoose.connection;
conn.on('connected', function () {
console.log("Database Connected");
})
var artistSchema = new mongoose.Schema({
artistName: String,
artistDob: String,
artistBio: String
})
const artists = mongoose.model("artist", artistSchema);
function addArtist(aName, aDOB, aBIO) {
const newArtist = new artists({
artistName: aName,
artistDob: aDOB,
artistBio: aBIO
})
newArtist.save((err, data, numAffected) => {
if (!err) {
return true;
}
else {
return false;
}
});
}
//MongoDb
app.get("/", (req, res) => {
res.sendFile(__dirname + "/index.html")
})
app.post("/addsongs", cors(), (req, res) => {
console.log("Add songs");
})
app.post("/addartist", cors(), (req, res) => {
var artistName = req.body.modalartistname;
var artistDOB = req.body.modalartistdob;
var artistBio = req.body.modalartistbio;
var addedArtist = addArtist(artistName, artistDOB, artistBio);
if (addedArtist) {
res.sendStatus(200);
}
else {
console.log("Failure")
res.sendStatus(400);
}
//console.log("Artist Added Sucessfully");
})
app.listen(3000, function () {
console.log("The Server is up and running");
})
i'm new to mongodb and dev web and i'm using mongodb with nodejs in this project and i got this problem "Cannot read properties of undefined (reading 'collection')" on postman when i send a request but in VS it connect to database without any problem could anyone help me please
here is my code
that's my connection.js and here when i hover on collection and db it says in visual code it's undefined
const {MongoClient} = require('mongodb');
const {dbURL, dbName} = require('../config');
const client = new MongoClient(dbURL, {
useUnifiedTopology: true,
useNewUrlParser:true
});
function Connect(){
return new Promise(async(resolve, reject) =>{
try {
await client.connect();
const db = client.**db**(dbName);
const users = db.**collection**('users');
users.createIndex({email: 1},{unique: 1});
resolve(db, client);
}catch(error){
reject(error);
}
});
};
module.exports = Connect;
i hope someone can find the solution here
and this is my index.js
const Connect = require('./connection');
const {port} = require('../config');
const app = require('./app');
Connect().then(({db}) => {
app.setupRoutes(db);
console.log('The database is connected');
}).catch((e) => {
console.error("couldn't connect to database", e);
});
app.listen(port, () => console.log(`App listening on port ${port}!`));
module.exports = app;
and that's my app.js
as you see i'm using db.collection here
const express = require("express");
const cors = require("cors");
const ValidationError = require('./errors/ValidationError');
const app = express();
app.use(cors());
app.use(express.json());
const handleNewUser = (user, db) => {
return new Promise(async(resolve, reject)=>{
try {
const users = db.collection('users');
const results = await users.insertOne(user);
resolve(results.insertedId);
}catch (error){
reject(error);
}
})
};
app.setupRoutes = (db) => {
app.post('/users',async (req, res) =>{
const user = req.body;
try {
const errors = validateUser(user);
if(errors.length > 0) throw new ValidationError(errors, 'Validation Error');
const results = await handleNewUser(user, db);
res.status(201).send(results);
}catch (error){
if(error instanceof ValidationError)
res.status(500).send({message:error.message,errors:error.errors});
else if(error.message.startsWith('E11000 duplicate'))
res.status(500).send('duplicate email.');
else res.status(500).send(error.message);
}
});
}
module.exports = app;
i donét know what's wrong and i'm following a tutoriel
resolve(db, client) - you resolve not object but separate values "db" and "client".
Connect().then(({db}) => { -
tries to destructure the 'db' property of the first resolved value, and if your "db" value is not an object or doesn't have .db property, it would always be undefined.
So remove destructuring and use just the value:
Connect().then((db) => {
I'm trying to get data from a collections database in my MongoDB using Node, which I've done successfully. My only problem is how to render the obtained data from the collections and posting it into the express app.
const { MongoClient } = require('mongodb');
const express = require("express");
const app = express()
async function main() {
const uri = "mongodb+srv://dbUser1:<password>#movies.uxfxv.mongodb.net/Movies?retryWrites=true&w=majority";
const client = new MongoClient(uri, {
useNewUrlParser: true,
useUnifiedTopology: true
});
MongoClient.connect(uri, function(err, db) {
if (err) throw err;
let dbo = db.db("Movies");
dbo.collection("Movies").find({}).toArray(function(err, result) {
if (err) throw err;
console.log(result);
db.close()
})
})
}
main().catch(console.error)
I solved my own problem by just performing an app.get() in the part were it says Mongoclient.connect() and the rest is done by logic, it displays now in the express and in postman as well.
const {MongoClient} = require('mongodb');
const express = require("express");
const app = express()
async function main() {
const uri = "mongodb+srv://dbUser1:<password>#movies.uxfxv.mongodb.net/Movies?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });
MongoClient.connect(uri, function(err, db) {
if (err) throw err;
let dbo = db.db("Movies");
dbo.collection("Movies").find({}).toArray(function(err, result) {
if (err) throw err;
console.log(result);
app.get("/", (req, res) => {res.json(result)})
db.close()
})
})
app.listen(4000, function() {
console.log("listening to port 4000)
}
main().catch(console.error)
Here is another way:
const MongoClient = require('mongodb').MongoClient;
const express = require('express');
const app = express();
const url = 'mongodb://localhost:27017';
const dbName = 'test';
const port = 3000;
app.listen(port);
// Type this in your browser to see db data: http://localhost:3000/
app.get('/', function(req, res) {
const client = new MongoClient(url, { useUnifiedTopology: true });
client.connect(function(err) {
console.log("Connected to server.");
const db = client.db(dbName);
db.collection("books")
.find({})
.toArray(function(err, result) {
if (err) throw err;
client.close();
console.log("Done reading db.");
res.send(JSON.stringify(result));
});
});
});
So I have this main server file index.js:
const express = require('express')
const app = express()
const route = require('./route')
app.use('/main', route)
app.listen(3000)
and then I have the route.js file:
const express = require('express')
const router = express.Router()
router.get('/', (req, res) => {
res.send('Hello from main')
})
module.exports = router
As the title implies, how could I make a global mongodb connection so that I don't have to make a new connection to the database on every route?
Thanks!
I'm surprised there is no answer on SO to this. The most common pattern is to initialize your database connection in a separate module and to import it in any file that needs it.
The below was taken from this longer article https://itnext.io/how-to-share-a-single-database-connection-in-a-node-js-express-js-app-fcad4cbcb1e and was written in callback style. I've updated it a little to be promise based below:
/* Callback Style */
const assert = require("assert");
const client = require("mongodb").MongoClient;
const config = require("../config");
let _db;
module.exports = {
getDb,
initDb
};
function initDb(callback) {
if (_db) {
console.warn("Trying to init DB again!");
return callback(null, _db);
}
client.connect(config.db.connectionString,
config.db.connectionOptions, connected);
function connected(err, db) {
if (err) {
return callback(err);
}
console.log("DB initialized - connected to: " +
config.db.connectionString.split("#")[1]);
_db = db;
return callback(null, _db);
}
}
function getDb() {
assert.ok(_db, "Db has not been initialized. Please called init first.");
return _db;
}
/******************************************************************/
//The client
const initDb = require("./db").initDb;
const getDb = require("./db").getDb;
const app = require("express")();
const port = 3001;
app.use("/", exampleRoute);
initDb(function (err) {
app.listen(port, function (err) {
if (err) {
throw err; //
}
console.log("API Up and running on port " + port);
});
);
function exampleRoute(req, res){
const db = getDb();
//Do things with your database connection
res.json(results);
}
Here's a promise based version without semi-colons which is how I might do it for itself. These functions would all become candidates for reuse between projects.
const assert = require("assert")
const client = require("mongodb").MongoClient
const config = require("../config")
let _db
module.exports = {
getDb,
initDb
}
function initDb() {
if (_db) {
console.warn("Trying to init DB again!");
return Promise.resolve(true)
}
return client.connect(config.db.connectionString,
config.db.connectionOptions)
}
function getDb() {
assert.ok(_db, "Db has not been initialized. Please called init first.")
return _db
}
//////////////////////
const {initDb, getDb} = require("./db")
const app = require("express")()
const port = 3001
app.use("/", exampleRoute)
initDb().
then(_ =>bootServer(port))
.catch(console.log)
function bootServer(port) {
app.listen(port, function (err) {
if (err) {
Promise.reject(err)
}
console.log("API Up and running on port " + port)
Promise.resolve()
})
}
function exampleRoute(req, res){
const db = getDb();
//Do things with your database connection
res.json(results);
}
What are best practicies to handle mongodb connection using mongoose on production?
This is my code
connectToDatabase.js
'use strict';
const mongoose = require('mongoose');
const mongodb = require('mongodb');
mongoose.Promise = require('bluebird');
const { Db, Server } = mongodb;
const database = 'test';
const connectToDatabase = (callback) => {
if (process.env.NODE_ENV == 'test') return false;
const db = new Db(database new Server('localhost', 27017));
db.open()
.then(() => {
mongoose.connect(`mongodb://localhost/${database}`, { config: { autoIndex: false } });
mongoose.connection
.once('open', () => {
console.log(`Connected to database ${database}`);
callback(db);
})
.on('error', (error) => {
console.warn('Warning', error);
});
});
};
module.exports = connectToDatabase;
app.js
const connectToDatabase = require('./connectToDatabase');
connectToDatabase(() => {
// run server
});
I don't know exactly what happening when connection to database is interrupted, Is mongoose trying connect to database again?