I'm currently setting up a custom Node server with Next.js. The fact that I'm using Next.js shouldn't make any difference though.
In previous apps, I've always used mongoose.connection.once('open', callback)
to start listening only when the database is open. This time, it's not working.
This is my connection configuration file:
import mongoose from 'mongoose';
import { MONGO_URI } from '../constants'; // looks like 'mongodb://localhost/my-db' in development
mongoose
.connect(MONGO_URI, () => {
try {
console.log(`Connected to ${MONGO_URI} with Mongoose.`);
} catch (err) {
throw err;
}
})
export default mongoose.connection;
I am importing this and using it in my main.ts file like so:
import express from 'express';
import next from 'next';
import * as dotenv from 'dotenv';
import logger from 'morgan';
import compression from 'compression';
import helmet from 'helmet';
import rateLimiter from './config/rateLimiter';
import db from './config/connection'; // This is the config file
dotenv.config();
const PORT = process.env.PORT || '8000';
const dev = process.env.NODE_ENV !== 'production';
const nxt = next({ dev });
const handle = nxt.getRequestHandler();
nxt.prepare().then(() => {
const app = express();
app.enable('trust proxy');
app.use(logger('dev'));
app.use(helmet());
app.use(rateLimiter);
app.use(compression());
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
db.once('open', () => {
app.listen(PORT, () => {
// This log never happens
console.log(`Listening on port ${PORT}.`);
});
});
});
It's extremely strange, because "Connected to mongodb://localhost/my-db with Mongoose.
" is in fact logged when using the code above, but the express app simply never listens; however, when I remove the app.listen
out of the db.once
callback function, "Listening on port 8000
" does of course get logged.
I'm stumped. Why isn't the 'open'
event firing? I've verified that mongo is working locally through the Mongo shell, and this same exact code was working when I had the folder which these files are in (server
) separate from the Next.js app (when I was still debating which type of view layer to write).
The issue is not compatibility. I'm running Mongo 5.0.5, and Mongoose 6.2.5, which should be find according to this
Please don't link to some other question. None of these have helped:
CodePudding user response:
The comment from @Shivam Sood was correct. The db.once('open')
was being called too late. Once nxt.prepare
had happened, the db was already opened.
Here is the modified code:
import express from 'express';
import next from 'next';
import * as dotenv from 'dotenv';
import logger from 'morgan';
import compression from 'compression';
import helmet from 'helmet';
import rateLimiter from './config/rateLimiter';
import db from './config/connection';
dotenv.config();
const PORT = process.env.PORT || '8000';
const dev = process.env.NODE_ENV !== 'production';
const nxt = next({ dev });
const handle = nxt.getRequestHandler();
db.once('open', () => { // Listen for 'open' event before nxt.prepare, and before listening on PORT
nxt.prepare().then(() => {
const app = express();
app.enable('trust proxy');
app.use(logger('dev'));
app.use(helmet());
app.use(rateLimiter);
app.use(compression());
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.get('*', (req, res) => {
return handle(req, res);
});
app.listen(PORT, () => {
console.log(`Listening on port ${PORT}.`);
});
});
});
CodePudding user response:
might be you need to try this way
import express from 'express';
import next from 'next';
import * as dotenv from 'dotenv';
import logger from 'morgan';
import compression from 'compression';
import helmet from 'helmet';
import rateLimiter from './config/rateLimiter';
import db from './config/connection'; // This is the config file
dotenv.config();
const PORT = process.env.PORT || '8000';
const dev = process.env.NODE_ENV !== 'production';
const nxt = next({ dev });
const handle = nxt.getRequestHandler();
nxt.prepare()
.then(async ()=>{
await db.once('open')
const app = express();
app.enable('trust proxy');
app.use(logger('dev'));
app.use(helmet());
app.use(rateLimiter);
app.use(compression());
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.listen(PORT, () => {
// This log never happens
console.log(`Listening on port ${PORT}.`);
});
})