When I try to import my routes module into the main app with app.use(require(./routes)) I get app.use() requires middleware functions. How should I go about the module.exports function to make it work?
My routes:
var express = require('express'),
auth = require('../middleware/auth.js'),
user = require('../models/user.js'),
formidable = require('formidable');
module.exports = (function () {
app.post('/', function (req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
user.create(fields.username, fields.email, fields.password);
});
res.render('./game/game.html', {});
});
app.get('/', function (req, res) {
res.render('./index.html', {});
});
app.get('/game', function (req, res) {
res.render('/views/index.html');
});
})();
My main app.js:
var express = require('express'),
app = require('express')(),
cookieSession = require('cookie-session'),
ejs = require('ejs'),
path = require('path'),
cookieParser = require('cookie-parser'),
util = require('util'),
port = process.env.PORT || 3000,
auth = require('./middleware/auth.js'),
user = require('./models/user.js'),
formidable = require('formidable');
router = express.Router();
app.use(express.static(path.join(__dirname, 'public')));
app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
//won't import routes
app.use(require('./routes'));
module.exports = router;
app.listen(port);
You need to return app in your exports function
module.exports = function (express) {
var app = express.Router();
app.post('/', function (req, res) {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
user.create(fields.username, fields.email, fields.password);
});
res.render('./game/game.html', {});
});
app.get('/', function (req, res) {
res.render('./index.html', {});
});
app.get('/game', function (req, res) {
res.render('/views/index.html');
});
return app
};
......
app.use(require('./routes')(express));
Your routes need to be an instance of Express Router.
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.send(req.headers);
});
module.exports = router;
Now in your app.js you can use them as following:
app.use('/', require('./routes/index'));
Your module should either mutate your router (app), or create its own router and export it.
Solution 1
Module
module.exports = function(app) {
app.post(...);
app.get(...);
}
Main app
require("./routes")(app)
Solution 2
Module
var app = express.Router();
app.post(...);
app.get(...);
module.exports = app;
Main app
app.use(require("./routes"))
Solution 2 is better in my opinion because it avoids mutation.
Related
app.js
const express = require("express");
const app = express();
app.use("/", require("./routers.js")(app));
app.listen(3000);
router.js
module.exports = function (app) {
console.log(app);
app.get("/", (req, res) => {
res.json(5);
});
};
The error given by the Console is: " TypeError: Router.use() requires a middleware function but got an undefined "
I don't understand why I can't pass the express app(app.js) through routers( in this way I don't redeclare the express and app variable in router.js ).
Don't pass app to routes better to create a new router and pass to the app.
router.js
const express = require("express");
const router = express.Router();
router.get("/", (req, res) => {
res.json(5);
});
module.exports = router;
app.js
app.use("/", require("./routers.js"));
As you mention in the comment, you don't have to add an inside app.use
module.exports = function (app) {
app.get("/", (req, res) => {
res.json(5);
});
};
// app.js
require("./routers.js")(app);
The use method of Express needs a callback of three parameters, not the app itself, so you need something like this:
In routes.js
exports.doSomeThing = function(req, res, next){
console.log("Called endpoint");
res.send("Called endpoint");
}
In your index.js
const Express = require("express");
const app = Express();
const routes = require("./routes");
app.use("/", routes.doSomeThing);
app.listen(3030, () => {
console.log("Listening on port 3030");
});
This approach doesn't need to include the express router but this may not be adecuate for big scale projects I recommend you to read express router documentation:
https://expressjs.com/es/guide/routing.html#express-router
I'm using express-subdomain.
The router that handles requests through a subdomain is the same as the router that handles requests without a subdomain.
I know that my 'app.js' setting is wrong.
How can I solve this problem? I want to know a good way. like this:
app.use(subdomain('banana', ('/about', bananaRouter);
and If this is an easy question, please forgive me. I couldn't find any of the same problems in my country. I'm sorry.
// /app.js
const appleRouter = require('./routes/apple/index');
const appleAboutRouter = require('./routes/apple/about');
const applePriceRouter = require('./routes/apple/price');
const bananaRouter = require('./routes/banana/index');
const bananaAboutRouter = require('./routes/banana/about');
const bananaPriceRouter = require('./routes/banana/price');
const grapeRouter = require('./routes/grape/index');
const grapeAboutRouter = require('./routes/grape/about');
const grapePriceRouter = require('./routes/grape/price');
app.use(subdomain('banana', bananaRouter));
app.use(subdomain('grape', grapeRouter));
app.use('/', appleRouter);
app.use('/about', appleAboutRouter);
app.use('/price', applePriceRouter);
app.use('/', bananaRouter);
app.use('/about', bananaAboutRouter);
app.use('/price', bananaPriceRouter);
app.use('/', grapeRouter);
app.use('/about', grapeAboutRouter);
app.use('/price', grapePriceRouter);
// /routes/apple/index
const express = require('express');
const router = express.Router();
router.get('/', function (req, res, next) {
res.send('I am Apple');
});
module.exports = router;
// /routes/apple/about
const express = require('express');
const router = express.Router();
router.get('/view', function (req, res, next) {
res.send("Apples don't taste good.");
});
module.exports = router;
// /routes/apple/price
const express = require('express');
const router = express.Router();
router.get('/view', function (req, res, next) {
res.send("$ 1");
});
module.exports = router;
// /routes/banana/index
const express = require('express');
const router = express.Router();
router.get('/', function (req, res, next) {
res.send('I am Banana');
});
module.exports = router;
// /routes/banana/about
const express = require('express');
const router = express.Router();
router.get('/view', function (req, res, next) {
res.send("Bananas are delicious.");
});
module.exports = router;
// /routes/banana/price
const express = require('express');
const router = express.Router();
router.get('/view', function (req, res, next) {
res.send("$ 2");
});
module.exports = router;
// /routes/grape/index
const express = require('express');
const router = express.Router();
router.get('/', function (req, res, next) {
res.send('I am Grape');
});
module.exports = router;
// /routes/grape/about
const express = require('express');
const router = express.Router();
router.get('/view', function (req, res, next) {
res.send("Grapes are purple.");
});
module.exports = router;
// /routes/grape/price
const express = require('express');
const router = express.Router();
router.get('/view', function (req, res, next) {
res.send("$ 3");
});
module.exports = router;
Expected Behaviour 2:
// http://localhost.com:3000/
I am Apple
// http://localhost.com:3000/about/view
Apples don't taste good.
// http://localhost.com:3000/price/view
$ 1
// http://banana.localhost.com:3000/
I am Banana
// http://banana.localhost.com:3000/about/view
Apples don't taste good. ** not Bananas are delicious. **
// http://banana.localhost.com:3000/price/view
'$ 1' ** not '$ 2' **
I created code sample which resolve you problem :D Firstly you need to add a couple lines to your /etc/hosts file. Example
127.0.0.1 banana.myapp.dev
127.0.0.1 myapp.dev
And after that try to run this script which I wrote for you:
//connect express
var express = require('express');
var subdomain = require('express-subdomain');
var app = express();
app.use(express.json());
//set sub routing
app.sub_banana = express.Router();
app.use(subdomain('banana', app.sub_banana));
//top level routing
app.get('/', (req, res) => {
res.send('I am Apple')
});
app.get('/about', (req, res) => {
res.send('Apples don\'t taste good.')
});
//subdomain routing
app.sub_banana.get('/', (req, res) => {
res.send('I am Banana')
});
app.sub_banana.get('/about', (req, res) => {
res.send('Apples don\'t taste good. ** not Bananas are delicious. **')
});
//start server
var http = require('http');
var port = 3000
app.set('port', port);
var server = http.createServer(app);
server.listen(port);
Let me know if you need more information. I got my answer from this resource https://exceed-team.com/tech/express-subdomain
I use express ejs on my backend and frontend. I have made a route to display the dashboard on the admin page. but I get 404 error to render view when I enter my url http: // localhost: 3000 /admin, here are some of my code:
app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var admin = require('./routes/admin');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(indexRouter);
app.use('/admin', admin);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// app.use((req, res, next) => {
// res.status(404).render('error/404')
// });
// error handler
app.use(function(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 : {};
// render the error page
res.status(err.status || 500);
res.render('error/404');
});
module.exports = app;
controller dashboard.js
exports.getDashboard = (req, res, next) => {
res.render('dashboard', {
pageTitle: 'Dashboard',
path: 'admin/page/dashboard'
});
};
my admin route admin.js
const path = require('path');
var express = require('express');
const adminController = require('../controllers/backend/dashboard');
var router = express.Router();
/* GET users listing. */
router.get('/admin', adminController.getDashboard);
module.exports = router;
thank you, please help me for this issue
in app.js you already have route /admin then again in admin.js, so it will be accessible with localhost:3000/admin/admin.
Change your admin.js to
const path = require('path');
var express = require('express');
const adminController = require('../controllers/backend/dashboard');
var router = express.Router();
/* GET users listing. */
router.get('/', adminController.getDashboard);
module.exports = router;
The problem is here:
const adminController = require('../controllers/backend/dashboard');
You are not exporting a default option from controller dashboard so you need to add curly braces like this:
const { adminController } = require('../controllers/backend/dashboard');
Try this and let me know! :)
I have declared socket.io in index.js file, And I would pass soket object to route module.
const express = require('express');
const app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var MongoClient = require('mongodb').MongoClient;
var server = require('http').Server(app);
var io = require('socket.io')(server);
var routes = require('./routes/routes')(io);
const dbb = mongoose.connect("mongodb://xxx:xxx#ds137600.mlab.com:37600/tasksdb");
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
app.use('/', routes);
var server= app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
routes.js
var express = require("express"); // call express
var taskSchema = require("../models/taskModel");
var mongoose = require("mongoose");
var router = express.Router(); // get an instance of the express Router
router
.route("/tasks")
.post(function (req, res, next) {
....
});
router
.route("/tasks")
.get(function (req, res) {
....
});
module.exports = router;
How can I transfert it to routes.js? what are the different ways to do it ? I still not well understanding how modules works
For server:
const app = express();
app.use(logger('tiny'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use((req, res, next) => {
const origin = req.headers.origin;
if (allowed_header.indexOf(origin) > -1) {
res.header('Access-Control-Allow-Origin', origin);
}
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, gutsyJwt, Accept'
);
next();
});
app.io = require('socket.io')({
origins: ['*:*'],
});
require('./routes')(app);
module.exports = app;
Then in route:
module.exports = app => {
app.post('/api/bar', (req, res) =>
fooController.bar(req, res, app.io)
);
};
Then in controller:
module.exports = {
bar(req, res, io) {
io.emit('message', req.body.message);
res.status(200).send({msg: 'Message broadcasted!'});
},
};
In this post, it is asking the similar question as well if you need more reference.
ExpressJS how do I pass objects with state (eg. connections)?
I have this router (http/api/ping.js):
var express = require('express');
var router = express.Router();
router.get('/ping', function (req, res) {
res.send("You called /api/ping");
});
module.exports = router;
This router is embedded into this router (http/api/index.js):
var express = require('express');
var router = express.Router();
router.get('/', function (req, res) {
res.send('You called /api');
});
router.use('/ping', require('./ping'));
module.exports = router;
And this router is used by my Express.js app (app.js):
var http = require('http');
var express = require('express');
var bodyParser = require('body-parser');
var logger = require('./config').logger;
// Create app
var app = express();
var server = http.createServer(app)
var io = require('socket.io')(server);
// App config
app.use(bodyParser.json());
app.use('/api', require('./http/api'));
// Display requests on console
app.use(function (req, res, next) {
logger.trace(req.method, req._parsedUrl.href);
next()
});
module.exports = {
app: app,
server: server
};
When I run the app, /api returns You called /api, but /api/ping gives me a 404.
I am using Node 6.9.1 and Express ^4.14.0
I think order matters in this scenario. Try putting /ping above the / get route.
router.use('/ping', require('./ping'));
router.get('/', function (req, res) {
res.send('You called /api');
});
Also in your ping route you say the path to your route is /ping you also say it is /ping when you import it to the other router, which would make the path /api/ping/ping
change
router.get('/ping', function (req, res) {
res.send("You called /api/ping");
});
to
router.get('/', function (req, res) {
res.send("You called /api/ping");
});
I think your routing is incorrect on this line
router.use('/ping', require('./ping'));
this will point to http/api/ping/ping
it should be
router.use('/', require('./ping'));