Why is Mongoose showing the deprecated warning after I have set the promise library?
Countless posts (example #1, example #2, etc.) say to set mongoose.Promise = global.Promise; to resolve this warning. I have even done it myself in the past! However, nothing I do prevents Mongoose from complaining about the promise library:
(node:54561) DeprecationWarning: Mongoose: mpromise (mongoose's default
promise library) is deprecated, plug in your own promise library instead:
http://mongoosejs.com/docs/promises.html
I'm using v4.8.7 with the following code:
var bodyParser = require('body-parser'),
config = require('./config'),
data = require('./data'),
express = require('express')
mongoose = require('mongoose'),
routes = require('./routes');
mongoose.Promise = global.Promise;
var db = mongoose.connection;
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(routes);
db.once('open', function() {
console.log('Database connected!');
data.seeds.doSeed(function(){
app.listen(3000, function() {
console.log('Mongo example listening on port 3000!');
});
});
});
mongoose.connect(config.db.uri, config.db.options);
You are using the underlying MongoDB driver, from the documentation
Promises for the MongoDB Driver
The mongoose.Promise property sets the promises mongoose uses. However, >this does not affect the underlying MongoDB driver. If you use the >underlying driver, for instance Model.collection.db.insert(), you need to >do a little extra work to change the underlying promises library. Note >that the below code assumes mongoose >= 4.4.4.
var uri = 'mongodb://localhost:27017/mongoose_test';
// Use bluebird
var options = { promiseLibrary: require('bluebird') };
var db = mongoose.createConnection(uri, options);
Band = db.model('band-promises', { name: String });
db.on('open', function() {
assert.equal(Band.collection.findOne().constructor, require('bluebird'));
});
I think this is a answer you are asking for.
Related
I have been using gridfs-stream with older versions (<4.11.0) of mongoose with the following settings:
var grid = require("gridfs-stream");
var mongoose = require("mongoose");
mongoose.connect(connectionString);
grid.mongo = mongoose.mongo;
var gfs = grid(mongoose.connection.db);
All works fine with these settings. After the update to mongoose 4.11.11 the mongoose connection setting should be changed to (3rd line):
mongoose.connect(connectionString, {useMongoClient: true});
However, now mongoose.connection.db is no longer defined. How should the above code be changed to make it work again? Many thanks.
I found a solution which makes use of deasync and with minimal changes to all my existing code. However it does not look ideal so any suggestions will be greatly appreciated:
var grid = require("gridfs-stream");
var mongoose = require("mongoose");
var deasync = require("deasync");
//Connect to mongodb
mongoose.Promise = global.Promise;
mongoose.connect(connectionString, {useMongoClient: true});
//Get the connection setting
var getConnDb = function () {
var connDb;
mongoose.connection.then(function (conn) {
connDb = conn.db;
});
while (connDb === undefined) {
deasync.runLoopOnce();
}
return connDb;
};
//Set gridfs-stream connection
grid.mongo = db.mongo;
var gfs = grid(getConnDb());
So I'm on a macbook running mongodb locally. Mongodb is listening on port 27017 and I can see it saying it's ready to accept connections. If I open a mongo shell, I can see it shows the connection. When I run "node index.js", the program just hangs and doesn't show and error or it doesn't show connected. Also, in the mongo server tab I can see connections accepted
Here's my code:
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var _ = require('lodash');
//create application
var app = express();
//add middleware
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
app.use(methodOverride('X-HTTP-Method-Overrise'));
mongoose.connect('mongodb://localhost:27017/boost', function(err) {
if (err) {
console.log(err);
}else{
console.log("Connected");
}
});
try this
mongoose.connect('mongodb://localhost:27017/boost', {useMongoClient:true});
mongoose.connection.once('open',function () {
console.log('Connected');
}).on('error',function (error) {
console.log('CONNECTION ERROR:',error);
});
There wasn't really anything wrong. I solved it by just doing and then writing my code later.
mongoose.connect('mongodb://localhost/boost');
var db = mongoose.connection;
I'm building a restful web service api using NodeJS.It uses Mongoose as ODM and using MongoDB for backend.
Below i will explain my scenario
I started nodejs server
After that i shutdown the MongoDB database.
Then call the GET api call,it doest catch any errors and api call get hang.
database config in main.js file
var mongoose = require('mongoose');
var uri = 'mongodb://localhost/mydb';
mongoose.Promise = global.Promise;
var options = { server: {socketOptions: { keepAlive: 300000, connectTimeoutMS: 10000 } } } ;
mongoose.connect(uri,options);
var db = mongoose.connection;
db.on('error',console.log.bind(console,'connection refused !!!!!'));
db.once('open', console.log.bind(console,'connection success !!!!!'));
this is my basic GET call
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var rootRes = require('../model/rootresources.js');
router.get('/', function(req, res, next) {
rootRes.find({},function (err, rootResource) {
if (err){
console.log('Error occurd !!!') }
res.json(rootResource);
});
});
Even database connection failed, the code does not goes to error block. So didn't capture the database refuse when database connection is failed in the API call.
I want to capture that error and send internal server error (code:500) to client. I tried to find the solution but still could not find it
Any solutions or do i made a mistake ?
Thank you
Amila
Did you put the two parts of code in the same file(ie. main.js) or two different files.
put them in the same file, and run node main.js do throw exceptions.
// main.js
var mongoose = require('mongoose');
var uri = 'mongodb://localhost/mydb';
mongoose.Promise = global.Promise;
var options = { server: {socketOptions: { keepAlive: 300000,
connectTimeoutMS: 10000 } } } ;
mongoose.connect(uri,options);
var db = mongoose.connection;
db.on('error',console.log.bind(console,'connection refused !!!!!'));
db.once('open', console.log.bind(console,'connection success !!!!!'));
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var rootRes = require('../model/rootresources.js');
router.get('/', function(req, res, next) {
rootRes.find({},function (err, rootResource) {
if (err){
console.log('Error occurd !!!') }
res.json(rootResource);
});
});
exceptions are:
connection refused !!!!! { MongoError: failed to connect to server [localhost:27017] on first connect [MongoError: connect ECONNREFUSED 127.0.0.1:27017]
etc...
So, I think maybe you put codes about express in a file like index.js and codes about mongoose connection in another file. And just run node index.js in command line. While running codes in index.js will not include codes in other files, codes in main.js will not be executed. As the result, there is no error info.
Updates
Two ways of I know two ways of doing this:
1.In main.js create function which creates connection to database and returns a instance of db so that you can call it function in you main code.
// main.js like this
var mongoose = require('mongoose');
function createConnection(url) {
mongoose.connect(url,options);
var db = mongoose.connection;
db.on('error',console.log.bind(console,'refused !!!!!'));
db.once('open', console.log.bind(console,'success !!!!!'));
return db;
}
// export function
module.exports = createConnection;
// in your index.js
var createConnection = require('./main.js');
var db = createConnection(url);
// other codes here
2.Using require or vm to compile and run javascipt code. You can find vm api detail here
//main.js
var mongoose = require('mongoose');
var uri = 'mongodb://localhost/mydb';
mongoose.Promise = global.Promise;
var options = { server: {socketOptions: { keepAlive: 300000,
connectTimeoutMS: 10000 } } } ;
mongoose.connect(uri,options);
var db = mongoose.connection;
db.on('error',console.log.bind(console,'connection refused !!!!!'));
db.once('open', console.log.bind(console,'connection success !!!!!'));
// index.js
// require will load file and execute automaticly
var scriptSrc = require('./main');
// other codes here
You can think of the second way as using eval('var mongoose = require('mongoose');
var uri = 'mongodb://localhost/mydb'; etc...)
mongoose connection do not happen unless you hit a request. so its best you handle it in your first request middleware. see code insight bellow.
module.exports = function () {
return function (req, res, next) {
mongoose.connect(URL, MONGO_OPTIONS);
mongoose.connection
.once('open', () => { })
.on('error', (error) => {
res.status(401).json({});
});
...
Then pass the middleware above to your router: let me know if you need more explanation
router.get('/', myMiddleware(){})
This is the error which is still being thrown when saving even after adding native promise.
(node:5604) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://127.0.0.1/optimusCP')
.then(function () {
console.log('Connected to MONGOD !!');
}).catch(function (err) {
console.log('Failed to establish connection with MONGOD !!');
console.log(err.message);
});
I have tried both bluebird & q, still haven't found a fix for this.
Below is the code when I save this, the following deprecation warning shows up..
var user = new User();
user.email = req.body.email;
user.password = hash;
user.save()
.then(function (user) {
console.log(user);
})
.catch(function (err) {
console.log(err);
});
This error is happening on the new version of mongoose which is 4.8.1, but working fine on 4.7.6 mongoose version.
Despite using mongoose.Promise = global.Promise; before mongoose.connect(...), I had the same warning.
I discovered, that I initialized mongoose connection in one file:
import mongoose from 'mongoose';
...
// Connect to MongoDB
mongoose.Promise = global.Promise;
mongoose.connect(mongoUri, mongoOptions);
mongoose.connection.on('error', (err) => {
console.error(`MongoDB connection error: ${err}`);
process.exit(1);
});
But I imported mongoose in another file too (where mongoose scheme was described), so I added mongoose.Promise = global.Promise; in second file too, as a result of it, the warning disappeared.
import mongoose, { Schema } from 'mongoose';
mongoose.Promise = global.Promise;
const UserSchema = new Schema({ ... });
May be you have the same case.
I've had success getting rid of the message with this
mongoose.Promise = Promise;
I have used bluebird for using promise with mongoose model functions node v6.9.4 :
mongoose.Promise = require('bluebird');
Upgrading Mongoose from 4.8.1 to 4.9.1 solved my problem.
I'd like to know how to work with connectivity to a database in MEAN stack application. In particular, when should I create a connection to a database and when should I destroy a connection to a database. Should I create and destroy a connection on every new HTTP request or should I store a once created connection and use it for any subsequent requests as long as possible. I use Mongoose as a modeling tool.
Here is an example.
This is my routes.js file with a route /index. A request to this route should fetch some date from MongoDb database. It bothers me how I connect and disconnect to a database now. Yes, I connect and disconnect to a database exactly as written in Mongoose docs, but it it the right way to do it in a serious production environment?
var express = require('express');
var router = express.Router();
var config = require('./db-config');
// I create a Mongoose instance as a module object,
// as opposite to create it in every request handler function below.
var mongoose = require('mongoose');
var productSchema = require('../db/productSchema'); // model schema is also a module-wide object
// And here is a request handler function.
// It is called on every request as a brand new.
// I create and destroy a database connection inside this request handler
router.get('/index', function(req, res, next) {
// I connect to a database on every request.
// Do I need to do it here in a request handler?
// May I do it outside of this request handler on a module-wide level?
mongoose.connect('mongodb://my_database');
// I create a new connection here in a request handler.
// So it lives only during this request handler run.
// Is this the right way? May I do it outside of this request handler
// on a module-wide level and somehow keep this connection and use it
// in every subsequent requests to this or any other route in the app?
var db = mongoose.connection;
db.on('connecting', function() {
console.log('connecting');
});
db.on('connected', function() {
console.log('connected');
});
db.on('open', function() {
console.log('open');
});
db.on('error', console.error.bind(console, 'connection error'));
db.once('open', function(cb) {
var Product = mongoose.model('Product', productSchema);
Product.find({category: "books"}, function(err, prods) {
if (err) return console.error(err);
// I close a connection here in a callback.
// As soon as successfully fetched the data.
// Do I need to close it after every request?
// What is the right place and time to do it?
db.close(disconnect);
res.json(prods);
});
});
})
Found some good answers:
https://softwareengineering.stackexchange.com/questions/142065/creating-database-connections-do-it-once-or-for-each-query
What are best practices on managing database connections in .NET?
Its best practice to have your db connection in a separate module (db.js)
var mongoose = require('mongoose')
mongoose.connect('mongodb://localhost/dbname', function(){
console.log('mongodb connected')
})
module.exports = mongoose
Each model should have a separate module that takes in the db connection (post.js)
var db = require('../db.js')
var Post = db.model('Post', {
username: {type: String, required: true},
body: {type: String, required: true},
date: { type: Date, required: true, default: Date.now }
})
module.exports = Post
Then whenever you need to use that data set just require it and make calls
var Post = require('/models/post')
Post.save()
Post.find()
This is an opinion based question I'd say. What I use for my app is
app.get('/', function (req, res) {
res.sendfile('index.html');
});
mongoose.connect('mongodb://localhost:27017/my_db');
This way I create a connection once rather than on every HTTP request. Your way should work fine but it seems you will have to connect and disconnect the db to your app way too many times specially when the app is in development.
You want your connection to act like a singleton so as mentioned in the answer above it makes sense to do it outside of, and preferable before your routes:
var compression = require('compression');
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
...
app.use(compression());
// db
var mongoose = require('mongoose');
var configDB = require('./config/database.js');
mongoose.connect(configDB.url); // connect to our database
config/database.js:
module.exports = {
'url' : '#localhost:27017/dbname'
};
This is my solution :
import express from 'express';
import mongoose from 'mongoose';
import { name } from '../package.json';
import * as localconfig from './local-config';
import debug from 'debug';
debug(name);
const app = express();
const port = process.env.PORT || 3000;
const mongoUrl = localconfig.credentials.MONGO_URL;
import usersRoutes from './routes/users/user-routes';
app.use('/v1/users', usersRoutes);
mongoose.connect(mongoUrl)
.then(() => {
debug('DB connection successful');
app.listen(port, '0.0.0.0', () => {
debug(`Running on port ${port}`);
});
})
.catch((err) => {
debug(err);
});
You should first check weather the connection is successful or not and only then listen to a certain port. This is my app.js file where all the routes are loaded, so you do not have to call the db connection in all your files. You have a single config file where all the config is done. Your router file user-routes.js will look something similar to this:
import express from 'express';
import User from '../models/user'
const router = express.Router();
router.get('/', (req, res, next) => {
User.find()
.then((response) => res.json(response))
.catch((err) => next(err));
});
module.exports = router;