extend expressjs res property - javascript

Currenty I am trying to add an error & notice function to my expressjs app. I thought that by calling
app.use(function (req, res, next) {
res.notice = function (msg) {
res.send([Notice] ' + msg);
}
});
the notice function would be attached to all res objects present in my application, enabling me to use it as follows:
app.get('something', function (req, res) {
res.notice('Test');
});
However, the example above does not work. Is there a way to accomplish what I'm trying to do?

You need to call next after adding notice method to res, and you need to add the middleware before routes definition.
var express = require('express');
var app = express();
app.use(function (req, res, next) {
res.notice = function (msg) {
res.send('[Notice] ' + msg);
};
next();
});
app.use(app.router);
app.get('/', function (req, res) {
res.notice('Test');
});
app.listen(3000);

Related

How to get data in one middleware from another?

I have two middleware functions attached to my app get request which works fine.
const express = require('express');
const app = express();
function fun1 (req, res, next) {
console.log('this is fun1')
next()
}
function fun2 (req, res, next) {
console.log('this is fun2')
next()
}
app.get('/', fun1, fun2, function (req, res, next) {
res.send('User Info')
})
app.listen(8080, () => console.log(`Listening on port 8080!`))
Now if I try to do next('test') in fun1 then it bypass fun2 and does 'test' output in browser window instead of 'User Info' which is correct. But how do I get data in fun2? I need to pass something from fun1 and get it in fun2 for further validation.
Assign it to req. You will have access to the same request and response objects through all middlewares.
Note that next('test') does not respond to the client or at least it is not meant to. It is meant to handle errors. Without an error handler and in development mode, Express shows these errors in the browser.
Read on:
Error handling in Express
You can do this by attaching a key-value pair with req` object.
Now how to do this,
const express = require('express');
const app = express();
function fun1 (req, res, next) {
req.MY_VAR = 'MY_VAL'; // setting the value
console.log('this is fun1')
next()
}
function fun2 (req, res, next) {
let myVar = req.MY_VAR; // retrieving the value
console.log(myVar); // MY_VAL
console.log('this is fun2')
next()
}
app.get('/', fun1, fun2, function (req, res, next) {
res.send('User Info')
})
app.listen(8080, () => console.log(`Listening on port 8080!`))
Now, why not next()? Generally, the value passed in next() will be received by the error argument in app.get('/', function (err, req, res, next) {} );

express next throwing error as next is not defined

I am trying to pass some predefined functions in the callback of app.post() method. I am getting next is not defined error. Below is my code. Please suggest where I am doing wrong or am I missing any concept here?
var express = require('express');
var app = express()
app.post('/api/signup', function(req, res) {
validateParams(req, res, next),
dbCall(req, res, next),
sendResponse(req, res)
})
where I have each function defined and imported and returning next() after my process.
my validateParams function is below :
validateParams = function(req, res, next) {
console.log("at validator ", req);
next();
}
module.exports = validateParams;
my dbCall function is below :
dbCall = function(req, res, next) {
console.log("at dbCall ", req);
next();
}
module.exports = dbCall;
my sendResponse function is below :
sendResponse = function(req, res) {
console.log("at dbCall ", res);
res.send("Response sent successfully");
}
module.exports = sendResponse;
You probably forgot to add the next argument in your callback.
app.post('/api/signup', function(req, res, next) {
validateParams(req, res, next),
dbCall(req, res, next),
sendResponse(req, res)
})
I think you are trying to use validateParams(req, res, next) and dbCall(req, res, next) as middleware functions. In this case, you need something like this:
const validateParams = (req, res, next) => {
// do stuff here
next();
}
const dbCall = (req, res, next) => {
// do stuff here
next();
}
app.post('/api/signup', validateParams, dbCall, function(req, res) {
sendResponse(req, res)
})
You can read more here

expressjs: how to use authentication function in another file attached to server.js?

Imagine that I have the following piece of code in server.js
function checkAuth(req, res, next) {
if (!req.session.user_id) {
res.sendFile(__dirname + '/login.html');
} else {
next();
}
}
app.get('/', (req, res) => {
res.sendfile(__dirname + 'login.html');
});
app.post("/login", (req, res) => {
if (req.body.userID === 'a' && req.body.password === 'b') {
req.session.user_id = req.body.userID;
res.redirect('main');
} else {
res.redirect('/');
}
});
app.get('/main', checkAuth, (req, res) => {
res.sendFile(__dirname + '/main.html');
});
app.get('/logout', (req, res) => {
delete req.session.user_id;
res.redirect('/');
});
require('./latestNews.js')(app);
require('./featuredNews.js')(app);
app.get('*', (req, res) => {
res.sendFile(__dirname + '/404.html');
});
app.listen(port, () => {
console.log("listening on " + port);
});
The user will first see the login page. Once he has logged in he can see the main page. Function checkAuth is used in app.get('/main',... in order to achieve this.
I attached two other files latestNews.js and featuredNews.js. Those includes also app.get, app.post, ... functions and looks like this:
module.exports = function(app){
app.get("/latestNews", (req, res) => {
res.sendFile(__dirname + '/latestNews.html');
});
}
Those are thus exported as modules and added to server.js as follows:
require('./latestNews.js')(app);
require('./featuredNews.js')(app);
I made a server.js, latestNews.js and featuredNews.js in order to separate the work and keep the code short instead of one long file.
My problem is now as follows:
How can I pass the 'checkAuth' function to the latestNews.js and featuredNews.js So I can use it like this ?
app.get("/latestNews", checkAuth (req, res) => {
res.sendfile(__dirname + '/latestNews.html');
});
You can create a new Router that has this check and is mounted to your app :
authorizedRouter = express.Router();
authorizedRouter.use( checkAuth );
app.use( '/', authorizedRouter );
require('./latestNews.js')(authorizedRouter);
require('./featuredNews.js')(authorizedRouter);
Just be careful where you mount your router. If you want to mount it at the / of your app, you should put it after all of your app.get/app.post declarations.

How to set dynamic route for static files in express

Currently, to serve static files im doing something like this:
app.use('/', express.static(__dirname + '/public/'));
// then i start the server
http.createServer(app).listen(port, function() {
console.log('HTTP Express server listening on port %s', port);
});
However, this sets the same directory for that path for every request, under all conditions. What I want to do is something like this that varies the response request to request:
http.createServer(app).listen(port, function() {
if (someCondition) {
app.use('/', express.static(__dirname + '/public/'));
}
else {
app.use('/', express.static(__dirname + '/public/someotherpath'));
}
console.log('HTTP Express server listening on port %s', port);
});
How can I do this?
You do it the other way around you modify url to make your desire effect
app.use('/', function(req,res,next){
if(condition){
req.url = newURL // add something to lead to different directory
}
next();
});
app.use('/', express.static(__dirname + '/public/'));
// then i start the server
http.createServer(app).listen(port, function() {
console.log('HTTP Express server listening on port %s', port);
});
Old question...but this is a quick solution...
If you want to keep all the functionality that comes with express.static, then you can just monkey-patch req.url (since it's just middleware):
const path = require('path');
const express = require('express');
const app = express();
// Dynamic path, but only match asset at specific segment.
app.use('/website/:foo/:bar/:asset', (req, res, next) => {
req.url = req.params.asset;
express.static(__dirname + '/static')(req, res, next);
});
// Just the asset.
app.use('/website/*', (req, res, next) => {
req.url = path.basename(req.originalUrl);
express.static(__dirname + '/static')(req, res, next);
});
the result of express.static() is a middleware function, so you can call it dynamically with your condition.
app.get('/', (req, res, next) => {
if (condition) {
express.static(__dirname + '/public/')(req, res, next);
} else {
express.static(__dirname + '/public/someotherpath')(req, res, next);
}
});
I also had that same problem now i fixed it by making a condition just like the below code
app.use("/", (req, res, next) => {
//check a condition if its false then return
if(1 !== 1)return
//After returned all conditions
next()
}, express.static("public"))
And this code checks if 1 is not 1 then wont show the files if 1 is 1 then it shows all public files :)
Based on your last comment: you can still do this within the router
app.get('/somepath', function(req, res){
if(req.someCondition){
res.sendFile('./path/to/appropriate/file.html');
} else {
res.sendFile('./path/to/different/file.html');
}
}
Leave express.static to serve your common files like js, css, and images. Send different html files using the .sendFile() method. This avoids having to use the renderer if you prefer not to use something like jade or ejs

Express 4 router.route: route not found

I'm running into a strange issue. The first route is working, but the parameterized route returns a 404 error.
var express = require('express');
var router = express.Router();
router.route('/')
.get(function (req, res, next) {
res.send('A list of vehicles.');
})
.post(function (req, res, next) {
res.send('You added a vehicle!');
});
router.route('/:id')
.get(function (req, res, next, id) {
res.send('Vehicle: ' + id);
})
.put(function (req, res, next, id) {
res.send('You edited vehicle: ' + id);
});
If I add this route:
router.route('/test')
.get(function (req, res, next) {
res.send('This is a test.');
});
...I can hit that endpoint. This also seems to work with another router I'm using, which is using router.get(path, function) and router.post(path, function) instead of the router.route(path).get()... methodology.
Am I missing something obvious here? I'm using Express ~4.12.
Gah, I'm an idiot. Just figured this out. I saw an example that used this function signature:
.get(function (req, res, next, id) {
res.send('Vehicle: ' + id);
})
This apparently doesn't work. I'm not sure if the http methods check the arity of the function, but this did work:
.get(function (req, res, next) {
res.send('Vehicle: ' + req.params.id);
})
I don't remember where I saw that example, but hopefully this helps someone.

Categories

Resources