How to get MongoClient object from Mongoose? - mongodb

I have to get the MongoClient object from mongoose connection object, so that I can reuse for Agenda or somewhere else where I need.
db.js
// Export the mongoose instance
module.exports = () => {
mongoose.Promise = global.Promise;
try {
console.log('DBURL:', dbConfig.url);
const { url, options } = dbConfig;
mongoose
.connect(url, options)
.then(() => console.log('DB Connected'), err => console.log(err, options));
mongoose.connection.on('connected', () => {
logger.log('info', 'Mongoose default connection opened');
});
mongoose.connection.on('error', (err) => {
// logger.log('error', 'Couldn't able to connect to MongoDB', err);
// Blow system on db error
logger.log('info', 'Mongoose default connection opened');
throw err;
});
mongoose.connection.on('reconnected', () => {
logger.log('info', 'Mongo connection reconnected', arguments);
});
mongoose.connection.on('disconnecting', () => {
logger.log('error', 'Mongoose connection disconnecting', arguments);
});
mongoose.connection.on('disconnected', () => {
logger.log('error', 'Mongoose connection disconnected', arguments);
});
} catch (e) {
console.log("Couldn't connect to mongo:", e);
}
return mongoose;
};

You can get the mongoClient with getClient() method as shown in the docs: getClient()
Basically you need to do something like this
const client = mongoose.connection.getClient()
So to use it with connect-mongo for example you could just export that from your db.js then import and use where needed.
//db.js
module.exports.client = mongoose.connection.getClient()
//app.js
const { client } = require('path to file')
const store = MongoStore.create({ client })

const mongoose = require("mongoose");
let options = { //Your options };
const mongoClient = new mongoose.mongo.MongoClient(URI, options)

config = require('./configs');
mongoose = require('mongoose');
module.exports = function() {
var db = mongoose.connect(config.db, config.mongoDBOptions).then(
() => {
console.log('MongoDB connected')
},
(err) => {
console.log('MongoDB connection error',err)
}
);
require('../app/models/xxx.server.model');
require('../app/models/yyy.server.model');
return db;};

You may get MongoClient Object by following this method:
const { MongoClient, ObjectID } = require('mongodb');
function(req, res) {
(async function mongo() {
let client;
try {
client = await MongoClient.connect(url, {useNewUrlParser: true});
debug('Connected correctly to server');
const db = client.db(dbName);
}

Related

Unable to close mongoose connection

I am unable to close mongoose connection when I am storing mongoose.connection in a variable called db and creating a separate method to closing the connection via variable db I have tried both method db.close & mongoose.disconnect()
const mongoose = require('mongoose');
var db;
const connectToDB = function (callback) {
let dbUrl;
if (environmentTokens.enviroment === "test") {
dbUrl = localDBUrl;
} else {
dbUrl = environmentTokens.mongoDBUrl;
}
mongoose.connect(dbUrl);
db = mongoose.connection
db.on('error', (err) => {
tracer.error('Connection error with database', err);
})
db.on('connected', () => {
tracer.info('Connected with database', dbUrl);
console.log('Mongoose default connection connected');
callback();
})
// db.on('disconnected', function () {
// console.log('Mongoose default connection disconnected');
// });
// mongoose.connection.close(function () {
// console.log('Mongoose default connection disconnected through app termination')})
};
const getDB = function () {
return db;
};
const disconnectDB = function () {
db.close(function () {
console.log('Mongoose default connection disconnected through app termination')})
// mongoose.disconnect(function () {
// console.log('Mongoose default connection disconnected through app termination')})
}
module.exports = {
connectToDB, disconnectDB, getDB
};
And calling the disconnectDB method from index.js file
process.on('SIGINT', () => {
disconnectDB();
process.exit()
})
I tried to close the connection using following method
mongoose.disconnect(function () {
console.log('Mongoose default connection disconnected');
});
mongoose.connection.close(function () {
console.log('Mongoose default connection disconnected through app termination')})
within disconnectDB method but non of them is closing the connection but when i am using these method inside connectToDB then i am able to close the connection. DOn't understand why this is behaving like this

how to retrieve/download image from mongoDB using GridFS in Next.js

I have uploaded a few images in MongoDB but cannot retrieve the images. I'm new to Next js, can anyone explain how I can make a "/api/retrieve?fileName='...'" get API to retrieve images from the database. The handler is being executed first then the db connection message is showing.
import nc from "next-connect";
import mongoose from "mongoose";
import Grid from "gridfs-stream";
import { GridFsStorage } from "multer-gridfs-storage";
export const config = {
api: {
bodyParser: false,
},
};
Grid.mongo = mongoose.mongo;
let gfs;
const conn = mongoose.createConnection(
process.env.mongoURI,
{
useNewUrlParser: true,
useUnifiedTopology: true,
},
(err) => {
if (err) {
console.err("file DB connection error", err);
process.exit();
}
console.log("file DB connected!");
gfs = Grid(conn.db, mongoose.mongo);
gfs.collection("images");
}
);
export default async function handler(req, res) {
if (req.method === "GET") {
console.log("request query: ", req.query);
try {
const file = await gfs.files.findOne({ filename: req.query.filename });
const readStream = gfs.createReadStream(file.filename);
readStream.pipe(res);
} catch (error) {
res.send("not found");
}
}
}
Thanks in advance.

Socket.io, Mongodb returning undefined to frontend

I want to use socekt.io for a new project I am building. I am using socket.io for a login component and will be using socket.io in the future to update pages like a chat app. I am also using mongoose to handle my mongodb connection. I am taking in a username, and returning a password to my front end to be bcryptjs compareSync hashed. The problem I am having is that whatever is returned to the front end is undefined. When I print out what is returned to the front end, it prints out the value I am looking for though. Something is going on between the backend emitting something, and the frontend receiving something but I don't know what is it exactly. Here is my code for the back end:
const express = require('express')
const socket = require('socket.io');
const http = require('http');
const router = require('./router');
const mongoose = require('mongoose');
let Player = require('../models/player.model');
require('dotenv').config();
const PORT = process.env.PORT || 5000;
const app = express();
const server = http.createServer(app);
const uri = process.env.ATLAS_URI;
mongoose.connect(uri, {useNewUrlParser: true, useCreateIndex: true,
useUnifiedTopology: true });
const connection = mongoose.connection;
connection.once('open',() => {
console.log('MongoDB database connection established successfully')
});
const io = socket(server);
io.on('connection', (socket) => {
console.log('We have a new connection');
socket.on('login', ({ username }, callback) => {
console.log(username);
Player.find({"username": username}, function (err, player) {
if(err) {
console.log("there has been an error"), {player: null}
}
socket.emit('id', { password: player[0]['password'].toString(), id : player[0]['_id']})
}) })})
app.use(router);
server.listen(PORT, () => console.log('Server is working'))
Here is my code for the front end:
const ENDPOINT = 'localhost:5000';
async function submitAccount (e) {
e.preventDefault();
socket.emit('login', { username });
socket.on("id", (response) => {
setPassword2(String(response['password']));
id = response['id']; console.log(id);
console.log(password2)
});
try {
if (bcrypt.compareSync(password, password2) == true) {
props.setCookie("id", id);
setAccess(true);
access2 = true;
console.log(access2)
console.log('works')
}
else {
setErrorType('Invalid Password')
setErrorMsg('There is an issue with your password. Please try again')
setOpenModal(true)
console.log(password);
console.log(password2);
}
}
catch {
setErrorType('Invalid Username')
setErrorMsg('This username does not exist. Please try another')
setOpenModal(true)
}
Thanks for the help!
When you do the socket.on, it should include the whole statement you are looking to change with the socket.io output. See below:
async function submitAccount (e) {
e.preventDefault();
socket.emit('login', { username });
socket.on("id", (response) => {
setPassword2(String(response['password']));
id = response['id']; console.log(id);
console.log(password2)
if (password2 != undefined) {
try {
if (bcrypt.compareSync(password, password2) == true) {
props.setCookie("id", id);
setAccess(true);
access2 = true;
console.log(access2)
console.log('works')
}
}

Heroku: My routes still pointing to localhost when deployed

I set up my NODE_ENV to production under APP>Settings>Config Vars on Heroku and set up a mongo.json file in my root directory:
{
"development": {
"host": "127.0.0.1:27017",
"dbName": "hillfinder"
},
"production": {
"PRODUCTION_DB_DSN": "mongodb+srv://***credentials***#hillfinder-qjxuo.mongodb.net/production?retryWrites=true&w=majority"
}
}
But it's still pointing to localhost:
This is the my server/index.js:
const express = require('express');
require('dotenv').config();
const nextJS = require('next');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var bodyParser = require('body-parser');
var auth = require('./lib/auth');
var cors = require('cors');
var morgan = require('morgan');
var HttpStatus = require('http-status-codes');
var PORT = process.env.PORT || 8016;
const { isBlockedPage, isInternalUrl } = require('next-server/dist/server/utils');
function NODE_ENVSetter(ENV) {
var environment,
environments = {
production: () => {
environment = process.env.PRODUCTION_DB_DSN;
console.log(`We are currently in the production environment: ${environment}`);
return environment;
},
test: () => {
environment = process.env.TEST_DB_DSN;
console.log(`We are currently in the test environment: ${environment}`);
return environment;
},
default: () => {
environment = process.env.DEVELOPMENT_DB_DSN;
console.log(`We are currently in the development environment: ${environment}`);
return environment;
}
};
(environments[ENV] || environments['default'])();
return environment;
}
var db = NODE_ENVSetter('production');
var mongoose = require('mongoose');
function errorHandler(err, req, res, next) {
// Set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// Log error
console.error(err.stack);
// Render the error page
res.status(err.status || 500);
// Default error message by HTTP code
res.render('error', {
title: HttpStatus.getStatusText(err.status),
message: HttpStatus.getStatusText(err.status)
});
}
async function start() {
const dev = process.env.NODE_ENV !== 'production';
const app = nextJS({ dev });
const server = express();
await app
.prepare()
.then(() => {
mongoose.connect(db, { useNewUrlParser: true });
mongoose.Promise = global.Promise;
mongoose.connection
.on('connected', () => {
console.log(`Mongoose connection open on ${db}`);
})
.on('error', err => {
console.log(`Connection error: ${err.message}`);
});
})
.catch(err => {
console.error(err);
});
server.set('view engine', 'html');
server.use('/uploads', express.static(__dirname + '/uploads'));
server.use(bodyParser.urlencoded({ limit: '50mb', extended: false }));
server.use(bodyParser.json({ limit: '50mb' }));
server.use(morgan('dev'));
server.use(cookieParser());
server.use(
session({
secret: 'very secret 12345',
resave: false,
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection })
})
);
server.use(auth.initialize);
server.use(auth.session);
server.use(auth.setUser);
console.log('auth.setUser ', auth.setUser);
server.use(cors());
server.use('/users', require('./users'));
server.use('/images', require('./images'));
// Redirect all requests to main entrypoint pages/index.js
server.get('/*', async (req, res, next) => {
try {
const pathName = req.originalUrl;
if (isInternalUrl(req.url)) {
return app.handleRequest(req, res, req.originalUrl);
}
if (isBlockedPage(pathName)) {
return app.render404(req, res, req.originalUrl);
}
req.locals = {};
req.locals.context = {};
const html = await app.renderToHTML(req, res, '/', {});
// Handle client redirects
const context = req.locals.context;
if (context.url) {
return res.redirect(context.url);
}
// Handle client response statuses
if (context.status) {
return res.status(context.status).send();
}
// Request was ended by the user
if (html === null) {
return;
}
app.sendHTML(req, res, html);
} catch (e) {
next(e);
}
});
// error handler
server.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.errorStatus = err.status;
res.locals.errorMessage = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
console.log('err.status ', err.status);
res.status(err.status).send(err.message);
});
server.listen(PORT, err => {
if (err) throw err;
console.log(`> Ready and listening on http://localhost:${PORT}`);
});
}
start();
How would I fix that so I can log on to MongoDB atlas?
Thank you in advance!

How to connect to MongoDb with Hapi.js?

Does anyone know how to connect to MongoDb while using the Hapi.js framework?
I have only managed to find one example (https://github.com/Marsup/hapi-mongodb), but this requires using a plugin and has no comments in the code!
Does anyone know of a simpler way?
The following (using mongoose) works pretty well for me:
var Hapi = require('hapi');
var mongoose = require("mongoose");
var server = new Hapi.Server();
server.connection({ port: 3000 });
var dbUrl = 'mongodb://localhost:27017/mydb';
var dbOtions = {
db: { native_parser: true },
server: { poolSize: 5 }
};
server.register([ /* plugins */], function (err) {
if (err) {
throw err; // something bad happened loading the plugins
}
// ... Register the routes
server.start(function () {
mongoose.connect(dbUrl, dbOtions, function(err) {
if (err) server.log('error', err);
});
});
});
I use a hapi plugin that I wrote that connects to mongo, handles errors to log and adds bluebird promises.
'use strict';
var bluebird = require('bluebird');
var mongoose = bluebird.promisifyAll(require('mongoose'));
exports.register = function(plugin, options, next) {
mongoose.connect(options.mongo.uri, options.mongo.options, function (e) {
if (e) {
plugin.log(['error', 'database', 'mongodb'], 'Unable to connect to MongoDB: ' + e.message);
process.exit();
}
mongoose.connection.once('open', function () {
plugin.log(['info', 'database', 'mongodb'], 'Connected to MongoDB # ' + options.mongo.uri);
});
mongoose.connection.on('connected', function () {
plugin.log(['info', 'database', 'mongodb'], 'Connected to MongoDB # ' + options.mongo.uri);
});
mongoose.connection.on('error', function (e) {
plugin.log(['error', 'database', 'mongodb'], 'MongoDB ' + e.message);
});
mongoose.connection.on('disconnected', function () {
plugin.log(['warn', 'database', 'mongodb'], 'MongoDB was disconnected');
});
});
return next();
};
exports.register.attributes = {
name: 'mongoose',
version: '1.0.0'
};
Blog post on user authentication with passport and Mongoose
Also be aware that Hapi's model is based off of plugins so read and re-read the docs on building your own.
Visit http://cronj.com/blog/hapi-mongoose
Complete sample project which can help you Repo Link https://github.com/gauravgupta90/Hapi-Mongoose-Angular
Config.js
module.exports = {
server: {
host: '0.0.0.0',
port: 8000
},
database: {
host: '127.0.0.1',
port: 27017,
db: 'DatabaseName',
username: '',
password: ''
}
};
Server.js
var Hapi = require('hapi'),
Routes = require('./routes'),
config = require('./config'),
Db = require('./database');
var server = Hapi.createServer(config.server.host, config.server.port, {
cors: true
});
server.route(Routes.endpoints);
server.start(function() {
console.log('Server started ', server.info.uri);
});
Database.js
var Mongoose = require('mongoose'),
config = require('./config');
Mongoose.connect('mongodb://' + config.database.host + '/' + config.database.db);
var db = Mongoose.connection;
db.on('error', console.error.bind(console, 'connection error'));
db.once('open', function callback() {
console.log("Connection with database succeeded.");
});
exports.Mongoose = Mongoose;
exports.db = db;
The following works for me:
const Hapi = require("hapi");
const Mongoose = require("mongoose");
const server = new Hapi.Server({ "host": "localhost", "port": 3000 });
Mongoose.connect('mongodb://localhost:27017/testdb', { useNewUrlParser: true }, (err) => {
if (!err) { console.log('MongoDB Connection Succeeded.') }
else { console.log(`Error in DB connection : ${err}`)}
});