I have a express js controller file created like this
Path: /controllers/usersController.js
// Register User
module.exports.register = function(req, res) {
...
}
// Login User
module.exports.login = function(req, res) {
...
}
// Forgot Password
module.exports.forgot_password = function(req, res) {
...
}
And I am using require() inside route file like this
Path: /routes/users.js
const usersController = require('../controllers/usersController')
router.post('/users/register', usersController.register)
router.post('/users/login', usersController.login)
router.post('/users/forgot_password', usersController.forgot_password)
This is all working fine. But my controller code is getting bigger and I want to split the userController.js into separate files so that I can have something like this
/controllers/users/index.js
/controllers/users/register.js
/controllers/users/login.js
/controllers/users/forgot_password.js
And /controllers/users/index.js needs to be the base controller which includes all these separate files. And I can simply use this index.js file into the router.
I am not sure how that is done. I tried doing module.export() method inside each separate js files and imported them inside /users/index.js file, but I am getting this error from router.
.post() requires callback functions but got a [object Undefined] not working
Note: I am not allowed to use es6 import statement :(
From whatever information I gathered from the question, you can split up the controller file by setting the module.exports to a required function in each separate file.
For example, for the /controllers/users/register.js
module.exports = function(req,res){...}
And then inside the /controllers/users/index.js
let register = require('./register.js');
router.post('/users/register', register);
And continue similarly for each controller function.
Related
Somewhat new, please bear with me. Trying to use passport to authenticate only specific routes in a website. The routes are in a separate file called blog_a.js. I have the following functions created in the main server.js file:
function checkAuthenticated(req, res, next) {
if (req.isAuthenticated()){
return next()
}
res.redirect('/login')
}
function checkNotAuthenticated(req, res, next) {
if (req.isAuthenticated()){
return res.redirect('/')
}
next()
}
However, I'm trying to pass the above functions into the blog_a.js module, so I can use them as middleware to protect the routes within that module.
I have tried to use module.exports = {checkAuthenticated, checkNotAuthenticated} at the bottom of the main 'server.js' file, and then use a let server = require('../server.js') line to import these functions to the module that contains the routes I want to protect.
However, the above server variable comes back as undefined, and I've tried several permutations / destructuring methods to try to import it. All to no avail, I keep getting the routes failing due to the "undefined" object--Error: Route.get() requires a callback function but got a [object Undefined].
How can I set up the authentication in the server.js file but then pass its authentication functions to be used as middleware within an individual route file?
I looked at this solution, but it doesn't clearly explain how to get the middleware functions from one module--server.js--to another module--blog_a.js.
I got the following response on Patreon from Kyle of Web Dev Simplified, and it worked like a charm!
"You should be able to just create another file that is called authMiddleware.js or something like that. Then in that file define and export the functions at the end (module.exports = { function1, function2 }). Now in the places you need those functions you should be able to import them like so (const { function1, function2 } = require('./authMiddleware'))."
So I followed Kyle's advice and created the following separate file authMiddleware.js:
function checkAuthenticated(req, res, next) {
if (req.isAuthenticated()){
return next()
}
res.redirect('/login')
}
function checkNotAuthenticated(req, res, next) {
if (req.isAuthenticated()){
return res.redirect('/')
}
next()
}
module.exports = { checkAuthenticated, checkNotAuthenticated }
... and then used the following require statements to get access to the functions:
-in main server.js --> const {checkAuthenticated, checkNotAuthenticated} = require('./authMiddleware.js')
-in router file blog_a.js --> const {checkAuthenticated, checkNotAuthenticated} = require('../authMiddleware.js')
Thanks!
I'm using the express generator to create the framework for a site, which by default includes this line in the layout.jade file:
h1= title
Which calls in the title 'Express' from a local variable (index.jade extends the layout.jade file). However, I can't for the life of me find out where it's getting the variable from.
Can anyone tell me where the express generator creates the file that creates this variable, given I have used the default settings.
Inside the routes directory inside the index.js file
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' }); // <= HERE in the res.render method
});
module.exports = router;
You will find the object, passed as the second argument to the render method, that includes the key value pair {title: 'Express'}
I have an Express.js project where I am allowing plugins to be loaded and unloaded at runtime. Plugins have access to the Expess.js router stack to register their paths just like a normal script would such as:
var express = require('express');
var router = express.Router();
module.exports = function(projectCoreObject) {
function Plugin() { }
// Plugin initialize called when a plugin is loaded.
Plugin.Initialize = function (done) {
// Register the router..
projectCoreObject.app.use('/', router);
};
// GET - /test
router.get('/test', function(req, res, next) {
res.send('Success!');
});
return Plugin;
};
While this all works great, I have the issue with unloading plugins removing their router from the stack.
Is there a proper way to remove a full router object from Express.js' stack at runtime? I can do individual middleware using their names but with a route like this example shows, the name is just 'router' in the stack.
I resolved this by using a named function trick to take an anonymous function and turn it into a named one. This way I can remove the router by its name then.
Ive a nodejs app with express-handlebars and i am wanting to define variable for things like the 'host' address for CSS and Javascript that are currently being imported in a header.hbs file that i call form within the specific layout.
Ive created a config.js file which has a number of variables i want to set and ive imported that into the app.js using:
var config = require('./config.js');
but then im lost as t where to go. for example i was thinkging if i can some how do something like this:
<link href="{{config.csshost}}basev1.css" rel="stylesheet" type="text/css" />
Can anyone provide some pointers, am stumped other than declaring these variable every time i load the template.
You would set the app locals:
var app = express()
app.locals = {
config: config,
templateVar: 'test'
}
Edit:
Your routes will look something like this:
app.get('/', function(req, res) {
res.render('index', {config: config});
})
What this does, is then update the app.locals variable in express to look like this:
app.locals = {
config: config
}
All the app.local variables are then accessible in your templates via:
{{config}}
//which is really
app.locals['config']
So, in your app.js where you configure express you would do this:
var app = express();
app.locals.config = require('./config')
app.get('/', function(req, res) {
return res.render('index')
})
(This should be a comment to sctskw's answer above, but I don't have enough reputation to do that.)
Rather than overwriting app.locals with a new object, it would be better to add new properties to the existing one, like this:
app.locals.config = config;
app.locals.templateVar = 'test';
The reason is that Express uses app.locals internally. Overwriting it would lose some useful variables Express provides. For example, we could use settings.env to detect the current running environment in a view template, which is defined as app.locals.settings.env by Express.
I'd like to do a simple link in express.
I put into the index.jade
a(href='/test', title='View test page') Test
created in /routes a test.js
/*
* GET test page.
*/
exports.test = function(req, res){
res.render('test', { title: 'Genious test' });
};
and a simple test.jade in /views
extends layout
block content
h1= title
p Test page
I added in app.js
app.get('/test', routes.test);
If I click on the link I get the error
Cannot GET /test
Ok. In your app.js add the following lines, and your problems will be solved.
var test = require('./routes/test.js')
app.get('/test', test.test);
This will definitely allow for your app to run and the link to be active.
Instead of creating routes/test.js, add this on to routes/index.js
exports.test = function(req, res){
res.render('test', { title: 'Test' });
};
Then app.get('/test', routes.test); will work as expected.
This worked for me:
Adding
exports.newpage = function(req, res){
res.render('newpage');
};
to /routes/index.js. Then adding
app.get('/newpage', routes.newpage);
under
app.get('/', routes.index);
at the bottom of server.js (or app.js).
Months after the fact, I'm going to answer this a different way. You simply wanted it to work and you got a solution for it to work. But, what if you really wanted another routes.js to handle more of your routes? Fear not node can handle this!
Assuming this structure,
- app.js
- routes/
- index.js
- foo.js
And, let's say you want the syntax in your app.js
app.get('/test', routes.foo.test);
For this, in routes.js add,
var foo = exports.foo = require('./foo');
Then in app.js you'll have,
var routes = require('./routes');
This will work, it'll allow you to say in app.js,
app.get('/test', routes.foo.test);
This will give you another level to organize your routes. I usually like to keep all of my routes organized under the routes object, but if you want to import directly into main you can too,
var foo = require('./routes/foo');
app.get('/test', foo.test);