Nodejs Express: Routes in separate files - node.js

I write my app.js including all the routes in the main file and everything was working well. After my goal was to make the project more clear by moving the routes in a different files but it is not working.
I'm passing an object instead of a middleware function and I don't know how to fix it in the right way.
So this is my app.js file:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var morgan = require('morgan');
var mongoose = require('mongoose');
var myRoutes = require('./app/routes/myRoutes.js');
...
//parser for getting info from POST and/or URL parameters
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
//for log requests to console
app.use(morgan('dev'));
app.use('/myRoutes', myRoutes);
app.get('/',function(req,res){
res.end('Welcome Page!');
});
//Server Start
app.listen(port);
console.log('server start at port ' + port);
And the app/routes/myRoutes.js contains the following code:
var express = require('express');
...
var myRoutes = express.Router();
myRoutes.get('/users',function(req,res){
...
});
myRoutes.post('/setup',function(req,res){
...
});
myRoutes.post('/remove', function(req,res){
...
});
module.export = myRoutes;
I also tried this:
var express = require('express');
var myRoutes = express.Router();
myRoutes.route('/')
.get(function(req, res, next){
res.end('myRoute Get');
})
.post(function(req, res, next){
res.end('myRoute Post');
});
module.export = myRoutes;
But again it seems not passing a middleware function.

My second option code
var express = require('express');
var myRoutes = express.Router();
myRoutes.route('/')
.get(function(req, res, next){
res.end('myRoute Get');
})
.post(function(req, res, next){
res.end('myRoute Post');
});
module.export = myRoutes;
is working fine! I just write it in a wrong way
module.export = myRoutes;
isntead of
module.exports = myRoutes;

Hi this is more of additional tips on the question. You main js file would definately need to load a lot of routes and i found importing all of them is a lot of work. Rather use require-dir module to load all the routes like
const loader = require('require-dir');
var app = express();
var routes = loader('./routes');
for (route in routes){
app.use("/"+route,routes[route]);
}
needless to say define all routes inside routes folder and export Router module in each one of them like
var router = express.Router();
router.get(....);
module.exports = router;

Related

Node express cannot get static file

This is the picture of my server
https://drive.google.com/file/d/1GA57RyYsc5ik1pSlLhAGtgGjbp_vLFoH/view?usp=sharing
When I go to http://localhost:3000/
I get the error message: Cannot Get/
myserver.js
// TODO: mount the tigers route with a a new router just for tigers
// exactly like lions below
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var _ = require('lodash');
var morgan = require('morgan');
var lionRouter = require('./lions');
var tigerRouter = require('./tigers');
app.use(morgan('dev'))
app.use(express.static('client'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// this is called mounting. when ever a req comes in for
// '/lion' we want to use this router
app.use('/lions', lionRouter);
app.use(function(err, req, res, next) {
if (err) {
res.status(500).send(error);
}
});
app.listen(3000);
console.log('on port 3000');
Whenever you are trying to visit any url on the browser , then browser makes a GET request to that url, in your case you are not sending any response on the url: "http://localhost:3000/. You can try something like this.
app.route('/*')
.get(function(req, res) {
res.sendFile(path.resolve("./client") + '/index.html'));
});
Check the naming you used, it shows myserver.js instead of server.js as in the picture you uploaded.
Check your routing on line 10 of you code
var lionRouter = require('./lions');
var tigerRouter = require('./tigers');
. try this edited codes
server.js
// TODO: mount the tigers route with a a new router just for tigers
// exactly like lions below
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var _ = require('lodash');
var morgan = require('morgan');
var lionRouter = require('./server/lions');
var tigerRouter = require('./server/tigers');
app.use(morgan('dev'))
app.use(express.static('client'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// this is called mounting. when ever a req comes in for
// '/lion' we want to use this router
app.use('/lions', lionRouter);
app.use(function(err, req, res, next) {
if (err) {
res.status(500).send(error);
}
});
app.listen(3000);
console.log('on port 3000');
Express static directory is given client but it is present on parent directory.
So i have resolve this issue with path module and now this will work for you.
// TODO: mount the tigers route with a a new router just for tigers
// exactly like lions below
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var _ = require('lodash');
var morgan = require('morgan');
var path = require('path')
var lionRouter = require('./lions');
var tigerRouter = require('./tigers');
app.use(morgan('dev'))
app.use(express.static(path.join(__dirname, '../client')));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// this is called mounting. when ever a req comes in for
// '/lion' we want to use this router
app.use('/lions', lionRouter);
app.use(function(err, req, res, next) {
if (err) {
res.status(500).send(error);
}
});
app.listen(3000);
console.log('on port 3000');
Your code works fine after commenting the following three lines of your code:
var lionRouter = require('./lions');
var tigerRouter = require('./tigers');
app.use('/lions', lionRouter);
Check if any error is present in LionsJS.

How to separate routes from app file in express framework

For example :
server.js file
var express = require('express'),
app = express(),
port = 3000,
routes = require('./app/routes/apiRoutes');
routes(app);
app.listen(port);
routes.js file
'use strict';
module.exports = function( app ) {
var api= require('../controllers/apiController');
app.route('/get').get(api.get);
};
apiController.js file
'use strict';
exports.get = function(req, res) {
// console.log( req.app ); // access it but it didn't work ?
// here want to access app to set cookie and changed cookie ?
};
if there is another way please help me thanks :)
If I correct understand your question, with routes you can do something like this:
In routes.js file:
var router = require('express').Router()
router.get('/home', function(req, res, next) {
res.render('index')
})
module.exports = router
In server.js file:
var mainRoutes = require('./routes.js')
app.use(mainRoutes)
Best way (in my opinion) to use controllers from another file it's use exports.functionName notation:
In someController.js file:
exports.homePage = function(req, res) {
res.render('index')
}
So, your router will looks like this:
var router = require('express').Router()
var someController = require('./someController.js')
router.get('/home', someController.homePage)
module.exports = router
Do different way, use route in app.use
app.js:
const
express = require('express'),
app = express(),
port = 3000,
routes = require('./app/routes/apiRoutes');
app.use(routes);
app.listen(port);
apiRoutes.js:
const
router = require('express').Router(),
apiController = require('../controllers/apiController');
router.get(
'/get',
apiController.get);
module.exports = router;
Check this example: app.js , some route file

ERROR app.use() requires middleware functions: (so how to set router for app.use in express node.js)?

basically im just trying to seprate routes, models, and controller in node.js application.
i have following files to setup very very basic node.js application.
controller/cv.js
module.exports = {
get: function(req, res, next){
console.log("GET REQUESTS")
next();
}
}
routes/cv.js
var express = require('express');
var CvRouter = express.Router();
var CvController = require('../controller/cv')
CvRouter.get('/', function(req, res, next){
console.log("GET REQUESTS")
next();
})
module.export = CvRouter
app.js
const express = require('express');
const bodyParser= require('body-parser')
var path = require('path')
const app = express();
app.use(bodyParser.urlencoded({extended: true}))
app.use(bodyParser.json())
var router = express.Router();
require('./router')(app)
app.listen(3000, function() {
console.log('listening on 3000')
})
router.js
var CvRouter = require('./routes/cv')
module.exports = function(app) {
app.use([CvRouter]);
};
Basicaly this last file router.js is generting error when i use app.use([CvRouter])
ERROR is: throw new TypeError('app.use() requires middleware functions');
how i can resolve it? i also know its returning object of router. and app.use expecting function in parameter. but how i can achieve my desired MVC pattern of node.js?
as said in comment - you have a typo.
The file routes/cv.js contains module.export instead of module.exports, that makes CvRouter undefined.
Kill the array literal
var CvRouter = require('./routes/cv')
module.exports = function(app) {
app.use(CvRouter);
};

Using Express Router in routes.js

I am currently using routes in app.js as below:
// Router configuration
var router = express.Router();
router.route('/user')
.get(userController.getUser)
.post(userController.postUser);
app.use('/api', router);
Is it possible to put Express router routes in another file like routes.js and call from app.js? I tried with app.get in routes.js and it is working. But it is annoying to add /api for prefix in all routes as below.
module.exports = function(app){
app.get('/user', userController.getUser);
};
Or, is there anyway to use namespace in app.get too? Thank you
Why not just do what you're doing, but in your route file?
var express = require('express');
var router = express.Router();
router.route('/user')
.get(userController.getUser)
.post(userController.postUser);
module.exports = function(app) {
app.use('/api', router);
};
Then you'd have in your app.js file
require('./routes.js')(app);
Routers support namespaces too, so you could even do
app.use('/', require('./routes.js'));
And in your routes file (this can be split across files for modularity)
var express = require('express');
var mainRouter = express.Router();
var userRouter = express.Router();
userRouter.route('/user')
.get(userController.getUser)
.post(userController.postUser);
mainRouter.use('/api', userRouter);
module.exports = mainRouter;
You don't need to declare your routes in app.js, in fact, it's better to have each route in its own file, so you can write a routes/my_route.js file as:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
Then in app.js:
var express = require("express");
var myRoute = require("./routes/my_route");
var app = express();
app.use("/my-route", myRoute);

Expressjs mounting api on different route "Cannot read property 'handle' of undefined"

What I am trying to achieve is my statics being loaded on / , with the api mounted at /api
Here is my main file:
var express = require('express');
var server = express();
var app = require('./api/app');
server.use(express.static('/', __dirname + '/public'));
server.use('/api', app(server));
server.listen(3000);
My app.js file:
module.exports = function(app) {
app.get('/users/:id', function(req, res, next){
res.json(req.params);
});
}
I am getting a Cannot read property 'handle' of undefined error. I still haven't quite got my head around express' use and i'm sure im making a very novice mistake but just not sure how I can configure to get the result I would like.
Thanks.
You should use a Router instead with Express 4.x:
// main.js
var express = require('express');
var server = express();
var api = require('./api/app');
server.use(express.static('/', __dirname + '/public'));
server.use('/api', api());
server.listen(3000);
// ./api/app.js
var router = require('express').Router();
module.exports = function() {
router.get('/users/:id', function(req, res, next){
res.json(req.params);
});
return router;
};
use expects to receive a middleware function, but in this example it's not actually getting anything (notice that there's no return value in app.js). One way to fix this would be to return an instance of express' Router middleware:
var express = require('express');
module.exports = function(app) {
var apiRouter = express.Router();
apiRouter.get('/users/:id', function(req, res, next){
res.json(req.params);
});
return apiRouter;
};

Resources