i come to you because i'm stuck for rewrite my url in javascript.
For example when user make a request for deposit page , my url looks like '/member/deposit' but i just want '/deposit'. i'm using a MVC architecture.
index.js // Where i define all routes file
const
homeRoute = require('./home'),
memberRoute = require('./member');
function init(server) {
server.get('*', function (req, res, next) {
res.locals.user = req.user || null;
return next();
});
server.use('/', homeRoute);
server.use('/member', memberRoute);
}
module.exports = {
init: init
};
router member.js // Where i define all member routes
const
express = require('express'),
memberController = require('../controllers/member');
let router = express.Router();
router.get('/*', function(req, res, next){
if (req.session.user && (req.session.user.role == "member"))
next();
else
res.redirect('/login');
});
router.get('/', memberController.deposit);
router.get('/deposit', memberController.deposit);
router.get('/withdraw', memberController.withdraw);
module.exports = router;
controller member.js // where all code is executed before rendering
function deposit(req,res){
res.render('member/deposit',{
title:'Deposit'
});
}
function withdraw(req,res){
res.render('member/withdraw',{
title:'Withdraw'
});
}
Any help would be appreciated, i've not find response on stackoverflow
It can be use this way:
server.use('/', homeRoute);
server.use('/', memberRoute);
As long as the link in homeRoute and memberRoute have no duplication.
Or
The complete rewrite of url can be done as in the following link:
https://gist.github.com/ramonfritsch/06893c1c561d670687a9aee3bbc4e9c7
Related
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);
In Node Js route.js when user try to open
app.use('/demo1', require('express').static(__dirname + '/demo1'));
then i want to redirect to
app.use('/demo2', require('express').static(__dirname + '/demo2'));
like
In the browser user type
http://locahhost:5010/demo1 this URL
but it will open
http://locahhost:5010/demo2 this URL
Use redirect in your route Express redirect
Example:
app.get('/demo1', function(req, res) {
res.redirect('/demo2');
});
app.use((req, res, next) => {
if (req.url == '/') {
res.redirect('/en');
return;
}
next();
})
I was thru the same and i had to use return next() was calling before
You probably created a route. To fix, change the about router from this:
app.get('/demo1', function(req, res) {
res.redirect('/demo2');
});
You can try this is as well if you have routes in seperate files. Let say we have it in demo1route.js in the route folder.
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.render('/demo2');
});
and then use below code in app.js
var demo1 = app.require('../demo1route.js')
app.use('/demo1',demo1);
app.get('/demo1', function(req, res) {
res.redirect('/demo2');
});
this should work fine if /demo2 is a get request router
So I'm trying to seperate my login routes in a seperate JS file called login_routes.js
I keep getting this specific error:
TypeError: Router.use() requires middleware function but got a Object
at Function. (/Users/ethanthomas/Desktop/mean-stuff/express-server/node_modules/express/lib/router/index.js:446:13)
Not entirely understanding what it's asking me to implement?
login_routes.js:
var express = require('express');
var app = express();
app.route('/login')
.get(function(req, res, next) {
res.send('this is the login form');
})
.post(function(req, res, next) {
console.log('processing');
res.send('proccessing the login form!');
});
server.js:
var express = require('express');
var app = express();
var path = require('path');
var adminRoutes = require('./app/routes/admin_routes');
var loginRoutes = require('./app/routes/login_routes');
app.use('/admin', adminRoutes);
app.use('/login', loginRoutes);
//send our index.html file to the user for the home page
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
//start the server
app.listen(1337);
console.log('leet is the magic port');
Your login_routes.js should look something like this (in the context of express):
var express = require('express');
var router = express.Router();
// GET request to /login
router.get('/', function(req, res, next) {
// do something
});
// POST request to /login
router.post('/', function(req, res, next) {
// do something
});
module.exports = router;
In your app.js you use
var login_routes = require('./login_routes');
...
app.use('/login', login_routes);
...
Have a look at the code generated by the express-generator module. That is a starting point for express webserver apps.
People have already offered hints at the solution in comments.
The first issue is that you need to export your "sub" app from login_routes.js. To do so, change this:
var app = express();
Into this:
var app = module.exports = express();
Secondly, you are—probably unintentionally—creating routes for GET /login/login and POST /login/login. To solve this, use this in login_routes.js:
app.route('/').get(...).post(...);
This is because the root path in your sub app (the one in login_routes.js) will get mapped to the path used in app.use() in your main app (server.js).
Do like this:
login_routes.js:
exports.get = function( req, res ) {
res.send('this is the login form');
};
exports.post = function( req, res ) {
console.log('processing');
res.send('proccessing the login form!');
};
server.js:
var loginRoutes = require('./app/routes/login_routes');
app.get('/login', loginRoutes.get);
app.put('/login', loginRoutes.post);
login_routes.js:
var express = require('express');
var app = express();
app.route('/login')
.get(function(req, res, next) {
res.send('this is the login form');
})
.post(function(req, res, next) {
console.log('processing');
res.send('proccessing the login form!');
});
module.exports = router;
just writ module.exports = router then it will be work
Here's a modified example from Express.js's routing guide:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.send('Birds home page');
});
router.get('/about', function(req, res) {
res.send('About birds');
});
...
app.use('/birds', router);
app.use('/fish', router);
This prints "About birds" when I visit both /birds/about and /fish/about.
How do I pass a parameter or something to the router so, in the controller functions, it can tell those two different routes apart?
For example, I'd like to see "Birds can fly" when visiting /birds/about and "Fish can swim" when visiting /fish/about.
Ideally, I'd like to be able to pass some "configuration object" so the mini-app does not need to know about all possible routes it may be mounted at (in pseudocode):
router.get('/about', function(req, res) {
res.send(magic_configuration.about_text);
});
....
magically_set_config(router, {about_text: "Bears eat fish"})
app.use('/bears', router);
Here's what I've come up with: I pass the "mini-app configuration" by assigning it to req:
app.use('/birds', function (req, res, next) {
req.animal_config = {
name: 'Bird',
says: 'chirp'
};
next();
}, animal_router);
app.use('/cats', function (req, res, next) {
req.animal_config = {
name: 'Cat',
says: 'meow'
}
next();
}, animal_router);
and then in my route I can access them:
var express = require('express');
var router = express.Router();
...
router.get('/about', function(req, res) {
var animal = req.animal_config;
res.send(animal.name + ' says ' + animal.says);
});
This approach allows to easily mount the "mini-app" at another location providing different configuration, without modifying the code of the app:
app.use('/bears', function (req, res, next) {
req.animal_config = {
name: 'Bear',
says: 'rawr'
};
next();
}, animal_router);
You're basically talking about injecting configuration to a router.
I have faced with similar problem and figured out that in theory you can export not a router itself, but rather function that accepts configuration and returns created and configured router.
So in your case calling code will look like:
var animal_router = require('./animal_router')
app.use('/birds', animal_router({
name: 'Bird',
says: 'chirp'
}));
app.use('/cats', animal_router({
name: 'Cat',
says: 'meow'
}));
While ./animal_router.js might look following:
var express = require('express');
// Create wrapper function that will adjust router based on provided configuration
var wrapper = function (animal_config) {
var router = express.Router();
router.get('/about', function(req, res) {
var animal = animal_config;
res.send(animal.name + ' says ' + animal.says);
});
return router;
}
module.exports = wrapper;
So, if you want to serve changes by url, then you can inject params like this:
router.get('/:animal/about', function(req, res) {
// here we have bird or fish in req.params.animal
if(req.params.animal == 'bird') {
res.send('Birds can fly');
} else if(req.params.animal == 'fish') {
res.send('Fish can swim');
} else {
res.send('Unknown animal');
}
});
app.use('/', router);
You can use req.baseUrl to figure that out.
You can add route params like so:
router.get('/about/:param1/:param2', function(req, res) {
//then you can call this handler through /about/1/sometext get these params from request object:
console.log(req.params.param1, req.params.param2); // 1, 'sometext'
res.send('About birds');
});
Or you can send parameters through query params:
router.get('/about', function(req, res) {
//then you can call this handler through /about?param1=1¶m2=sometext get these params from request object as well:
console.log(req.query.param1, req.query.param2); // 1, 'sometext'
res.send('About birds');
});
I have defined multiple route middleware and want to share them across multiple routes/controllers.
Here is my setup:
app.js requires ./routes/index.js:
// load fs module
var fs = require('fs');
// import routing files
module.exports = function(app){
fs.readdirSync(__dirname).forEach(function(file) {
if (file == "index.js") return;
var name = file.substr(0, file.indexOf('.'));
require('./' + name)(app);
});
};
index.js loads all routes automaticly in the dir. A possible routes file can look like:
module.exports = function(app) {
app.get('/contacts', function(req, res, next) {
// routing stuff
});
};
Now I got route middleware:
function isAuthenticated(req, res, next) {
if (!req.session.authenticated) return next(new Error('user not authenticated'));
};
function loadUser(req, res, next) {
var query = User.findById(req.session.user_id);
query.populate('contacts');
query.exec(function(err, user) {
if (err) return next(err);
req.user = user;
next();
});
}
which I want to use like:
var User = require('../models/user');
module.exports = function(app) {
app.get('/contacts', isAuthenticated, loadUser, function(req, res, next) {
res.json(req.user.contacts);
});
};
I also would like to avoid requiring them accross all routing files.
A possible solution would also be:
// load fs module
var fs = require('fs');
var routeMiddleware = {
loadUser: function(req, res, next) { // logic },
isAuthenticated: function(req, res, next) { // logic },
};
// import routing files
module.exports = function(app){
fs.readdirSync(__dirname).forEach(function(file) {
if (file == "index.js") return;
var name = file.substr(0, file.indexOf('.'));
require('./' + name)(app, routeMiddleware);
});
};
but I think not the best...
Personally I would declare shared middleware in the app, not in the controllers, i.e.:
routes/home.js:
module.exports = function(req, res, next) { \\ Code }
app.js:
app.get('/', thisMiddleware, thatMiddleware, require('./routes/home'))
You can also make a stack (array, not an object):
theseMiddlewares = [thisMiddleware, thatMiddleware]
app.get('/', theseMiddlewares, require('./routes/home'))
And if these middlewares are used on all routes except a few, you can do the following:
theseMiddlewares = function(req, res, next) {
if (req.url.match(some_regex_for_urls_to_skip)) next()
else {
\\ do stuff...
next()
}
}
Now you can app.use(theseMiddlewares) that middleware, or if it needs to happen in a certain order relative to other middleware, you can use app.all('*', theseMiddlewares)