Separating Express.js-Routes into separate Files - javascript

I'm using express.js and am trying to separate my routes in a separate file.
This is an excerpt from my ./app.coffee:
viewsRouter = express.Router()
routesCallingViews = require('./app/routes/callingViews')
app.use '/', routesCallingViews.showApp viewsRouter, user, data
app.use '/', routesCallingViews.showSignUpForm viewsRouter
app.use '/', routesCallingViews.showLogInForm viewsRouter
the ./app/routes/callingViews looks like:
module.exports =
showApp: (router, user, data) ->
router.get '/', user.isSignedIn, (req, res) ->
...
showSignUpForm: (router) ->
router.get '/signup', (req, res) ->
...
showLogInForm: (router) ->
router.get '/login', (req, res) ->
...
I get this error:
Error: Route.get() requires callback functions but got a [object Undefined]
Any suggestions?

Common way to do what you are trying would be to extract all related routes to separate module where you would create and export instance of router, something like:
// foo.js
'use strict'
const express = require('express')
const router = express.Router()
router.get('/', (req, res, next) => { ... })
router.post('/bar', (req, res, next) => { ... })
...
module.exports = router
Then from whatever place (usually from server.js) you would hook all routers that you have, something like:
const fooRoutes = require('./foo')
app.use('/foo', fooRoutes)
So you will end up with:
GET /foo
POST /foo/bar

Related

Express - set routes in one routes

index.js
app.use('/',wowYeah);
app.use('/lol',wow);
how to use only
routes.js
app.use('/',wowYeah);
app.use('/lol',wow);
app.use(routes());
but it can't
how to do it?
1 app use for all routes
// birds.js file
const express = require('express')
const router = express.Router()
// middleware that is specific to this router
router.use(function timeLog (req, res, next) {
console.log('Time: ', Date.now())
next()
})
// define the home page route
router.get('/', function (req, res) {
res.send('Birds home page')
})
// define the about route
router.get('/about', function (req, res) {
res.send('About birds')
})
module.exports = router
// index.js file
const birds = require('./birds')
// ...
app.use(birds)
for more look documentation.

Route requiring a middleware function

I'm creating my routes module in nodejs with socket.io
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
module.exports = function (io) {
router.use(function (req, res, next) {
io.sockets.emit('payload');
console.log("Something is happening.");
next();
});
router
.route("/tasks")
.post(function (req, res, next) {
...
});
router
.route("/tasks")
.get(function (req, res) {
...
});
};
When I compile server I get this error
TypeError: Router.use() requires a middleware function but got a undefined
It appears to me that the problem is probably in the code that loads this module because you never export the actual router. So, assuming you do app.use() or router.use() in the caller who loads this module, your aren't returning the router from your function so there's no way to hook that router in and you would get the error you see.
I'm guessing that you can fix this by just returning the router from your exported function:
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
module.exports = function (io) {
router.use(function (req, res, next) {
io.sockets.emit('payload');
console.log("Something is happening.");
next();
});
router
.route("/tasks")
.post(function (req, res, next) {
...
});
router
.route("/tasks")
.get(function (req, res) {
...
});
return router; // <=========== Add this
};
Then, when you do:
let m = require('yourModule');
router.use(m(io));
Then function will return the router that router.use() will be happy with. You can pass either middleware or a router to .use().
If this guess isn't quite on target, then please show us the code that loads and calls this module.
When that function is called it's gonna return the equivalent of undefined. Also, normally a route is defined before the endpoint. It's typically structured like:
let myRouter = new Router();
Router.use('something', middlewareFunction, someotherprocess);

Add prefix in rest apis in nodejs

I have a server.js file in which I have required services.js that further requires all the other API files
require('./web_services/services')(app);
I have two other files Users.js and Events.js that holds the actual apis. The services.js require both the files
var logger = require("../logger/logger");
module.exports = function (app) {
require('./User/Users')(app,logger);
require('./Event/Events')(app,logger);
// in case of api error
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.send({ 'status': res.status, 'message': err });
logger.error(err);
});
}
Now I want to prefix /users before users apis and events/ before event apis.
I have tried
app.use('/user/', require('./User/Users')(app));
Users.js
module.exports = function (app, logger) {
// apis
};//exports
but this is not working? Am i missing something?
I believe you can solve your problem by using express routing
You can initialize router in service.js and then pass it around to enable routes and middleware in it and can define prefix in it in the service file as you were trying to do.
// service.js
var express = require('express')
var router = express.Router();
...
app.use('/users', require('./User/Users')(router, logger));
app.use('/events', require('./Event/Events')(router, logger));
...
All the routes in this file will be prefixed by the /users because we have mentioned it in the service file.
// Users.js
module.exports = function (router, logger) {
// middleware that is specific to this router
router.use(function timeLog (req, res, next) {
logger('users middleware', req); // or however you are using your logger
next();
})
// this route will be `/user/`
router.get('/', function (req, res) {
res.send('Users home page')
})
// this route will be `/users/about`
router.get('/about', function (req, res) {
res.send('About users')
})
return router;
};//exports
It's pretty straight forward I guess. You can refer this boilerplate, I made a while back ago using express and express router. Some naming convention is not good but yeah you can see how the router is defined and used in the boilerplate to enable route prefixing and middleware for specific routes.

Route parametrs empty in Express

I try print router parametrs but req.params is empty, don't know what I'm doing wrong.
In app.js:
...
var shareFile=require('./controllers/file/share');
...
app.use('/share/:id', shareFile);
...
And share.js controller:
var express = require('express');
var router = express.Router()
router.get('/', function (req, res, next) {
res.send(req.params)
});
module.exports = router;
localhost:3000/share/123 gives empty json page. Changing res.send to console.log gives {}.
Thanks
req.params will produce {id: 'abc'} when the routing is defined as /share/:id and you made the call to http://yourserver/share/abc
router.get('/', function (req, res, next) {
res.send(req.params)
});
Above you should expect that req.params will be empty here because your are not expecting them. But you should see them here:
router.get('/share/:id', function (req, res, next) {
res.send(req.params)
});

Express js 4x :req.params returns empty object

Trying to get URl parameters in express js,but got empty object.
var password= require('./routes/password');
app.use('/reset/:token',password);
password.js
router.get('/', function(req, res, next) {
console.log(req.params);
res.send(req.params);
});
console.log(req.params) output is {}
Access url :http://localhost:3000/reset/CiVv6U9HUPlES3i0eUsNwK9zb7xVZpfHsQNuzMNWqLlGA4NJKoagwbcyiUZ8
By default, nested routers do not get passed any parameters that are used in mountpaths from their parent routers.
In your case, app is the parent router, which uses /reset/:token as a mountpath, and router is the nested router.
If you want router to be able to access req.params.token, create it as follows:
let router = express.Router({ mergeParams : true });
Documented here.
You are getting params and query mixed up.
Query approach
Your code should look like this when using query values for the example url: www.example.com?token=123&foo=bar
router.get('/', function(req, res, next) {
console.log(req.query);
console.log(req.query.token); // to log value of token
console.log(req.query.foo); // to log value of foo
res.send(req.query);
});
Params approach
Your code should look like this when using params values for the example url: www.example.com/123
router.get('/:token', function(req, res, next) {
console.log(req.params);
console.log(req.params.token); // to log value of token
res.send(req.params);
});
Instead you can use a middleware to log the path params:
const logger = (req, res, next)=>{
console.log(req.params)
res.send(req.params)
next()//<----very important to call it.
};
app.use(logger); //<----use to apply in the app
router.get('/', (req, res, next)=>res.send('Logged.'));
Actually you messed it up a little bit. You have to pass instance of express to your module.
Server.js:
//adding modules
require('./routes/password')(app);
Password.js:
module.exports = function(router) {
router.get('/reset/:token', function(req, res, next) {
console.log(req.params);
res.send(req.params);
});
//and so on.. your routes go here
}

Categories

Resources