Reputation: 577
'use strict';
module.exports = function (app) {
console.log("before route creation");
app.get("/api/test", (req, res) => {
res.send("it worked");
});
console.log("routes created");
};
In the server.js file, I am importing this module as apiRoutes
. Then, I am calling it inside an async function.
const databaseConnection = async (apiRoutes, app) => {
try {
await mongoose.connect(`mongodb+srv://replitUser:${process.env.DB_PW}@issuetracker.pbbm6.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`);
console.log("db connection successful");
//Routing for API
console.log("apiRoutes called");
apiRoutes(app);
} catch (err) {
console.log("an err occurred", err);
}
}
databaseConnection(apiRoutes, app);
// apiRoutes(app);
The strings "before route creation"
and "routes created"
are logged to the console. However, the route does not seem to work, although no errors are occurring.
If I call apiRoutes
outside of the async function, like here:
const databaseConnection = async (apiRoutes, app) => {
try {
await mongoose.connect(`mongodb+srv://replitUser:${process.env.DB_PW}@issuetracker.pbbm6.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`);
console.log("db connection successful");
//Routing for API
// console.log("apiRoutes called");
// apiRoutes(app);
} catch (err) {
console.log("an err occurred", err);
}
}
databaseConnection(apiRoutes, app);
apiRoutes(app);
...it will create the test route successfully.
const databaseConnection = async (apiRoutes, app) => {
try {
await mongoose.connect(`mongodb+srv://replitUser:${process.env.DB_PW}@issuetracker.pbbm6.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`);
console.log("db connection successful");
//Routing for API
// console.log("apiRoutes called");
// apiRoutes(app);
app.get("/api/test", (req, res) => {
res.send("it worked");
});
} catch (err) {
console.log("an err occurred", err);
}
}
databaseConnection(apiRoutes, app);
Upvotes: 0
Views: 416
Reputation: 577
At first, I thought that using express.Router()
was an easy fix.
Here is what this would have looked like:
Create a router and mount it to the /api path:
const router = express.Router();
app.use("/api", router);
Then, create the route with router.get()
instead of app.get()
.
const databaseConnection = async (router) => {
try {
await mongoose.connect(`mongodb+srv://replitUser:${process.env.DB_PW}@issuetracker.pbbm6.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`);
console.log("db connection successful");
//Routing for API
router.get("/test", (req, res) => {
res.send("it worked");
});
} catch (err) {
console.log("an err occurred", err);
}
}
databaseConnection(router);
Here is a link to the complete version of this
I didn't understand that there is no need to create the routes after the database connection. Mongoose lets you use models before the database is connected because mongoose buffers these database calls internally. The server just needs to listen after the database connection.
So now I've implemented @num8er's thoughts and updated the project!
I've got a db.js
module, which exports a connect
function that returns a promise:
const mongoose = require("mongoose");
module.exports = {
connect: function() {
const dsn = `mongodb+srv://replitUser:${process.env.DB_PW}@cluster0.m31tz.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`;
return mongoose.connect(dsn);
},
}
In the server.js
file, I create the routes just by executing the api.js
module:
const apiRoutes = require("./routes/api.js");
const router = express.Router();
app.use("/", router);
apiRoutes(router);
And then I start listening after I'm connected to the database:
(async () => {
const db = require("./db");
try {
await db.connect();
console.log("connected to db");
} catch (err) {
console.log("an error occurred while connecting to db", err);
}
//Start our server and tests!
const listener = app.listen(process.env.PORT || 3000, function () {
console.log("Your app is listening on port " + listener.address().port);
if (process.env.NODE_ENV === "test") {
console.log("Running Tests...");
setTimeout(function () {
try {
runner.run();
} catch (e) {
console.log("Tests are not valid:");
console.error(e);
}
}, 5000);
}
});
})();
Attention: There is a problem with the chai tests on replit, as explained here. However, if you download the files and run the server locally, everything works fine.
Upvotes: 0
Reputation: 19372
I know it's not direct answer to Your question.
But the problem is that You cannot structure Your code correctly.
So in below You can see app structure with separate db and app module where app starts listening after db connection.
server.js
const http = require('http');
const db = require('./db');
const app = require('./app');
const server = http.createServer(app);
const PORT = process.env.PORT || 8000;
(async () => {
await db.connect();
console.log('connected to db');
server.listen(PORT, () => {
console.log(`app listening at port: ${PORT}`);
});
})();
db.js
const mongoose = require('mongoose');
const UserSchema = require('./schemas/User');
mongoose.model('User', UserSchema);
module.exports = {
connect: function() {
const dsn = `mongodb+srv://replitUser:${process.env.DB_PW}@issuetracker.pbbm6.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`;
return mongoose.connect(dsn);
},
model: function(name) {
return mongoose.model(name);
},
};
app.js
const express = require('express');
const app = express();
const routes = require('./routes');
app.use(routes);
module.exports = app;
routes/index.js
const express = require('express');
const router = express.Router();
const users = require('./users');
router.use('/api/users', users);
module.exports = router;
routes/users.js
const express = require('express');
const router = express.Router();
const db = require('../db');
const User = db.model('User');
router.get('/', async (req, res) => {
const users = await User.find({}).lean();
res.status(200).send({users});
});
router.get('/:id', async (req, res) => {
const user = await User.findById(req.params.id).lean();
if (!user) {
return res.status(404).end();
}
res.status(200).send(user);
});
module.exports = router;
schemas/User.js
const mongoose = require('mongoose');
const {Schema} = mongoose;
const UserSchema = new Schema({
username: Schema.Types.String,
password: Schema.Types.String,
name: Schema.Types.String,
});
module.exports = UserSchema;
Upvotes: 1