While using express.js for handling various routes I want to encapsulate all of my route code in a seperate module, but how can I access the req and res object across modules, See the code below
The main file examples.js is written as follows
var app = require('express').createServer();
var login = require('./login.js');
app.get('/login', login.auth(app.req, app.res));
app.listen(80);
What I want is that the login handling code be written in a seperate module/file called login.js, the question then is how will the response object be accessible in login.js. I think the following code will not work as because the type of req and res is not resolved.
exports.auth = function(req, res) {
res.send('Testing');
}
Hence when I start the server with node example.js I get the error
'Cannot call method send of undefined'
How is the Request and REsponse objects passed along modules
This should work:
app.get('/login', login.auth);
Your example was attempting to pass the return value of the login.auth function as get handler for the request. The above instead passes the login.auth function itself as the handler.
TJ Holowaychuk made some great examples for express on the github page, here's the one about route separation:
https://github.com/visionmedia/express/tree/master/examples/route-separation
Related
Hello I am new to NodeJs. Currently I am working in node with Express framework.
I installed the express-back package in my project and now I want to send send back data to view from where post request fired.
Below is my code that I write:
routes.js
router.post('/register/user',Rules.UserRules.registerUser,UserController.registerUser)
UserController.js
const {check, validationResult} = require('express-validator');
registerUser = function (req, res, next) {
// Validate request parameters, queries using express-validator
const errors = validationResult(req)
console.log("==== errors ===")
console.log(errors.array())
if (!errors.isEmpty()) {
console.log("==== erorror founded ====")
return res.redirect('/signup',{errors:errors})
}else{
console.log('--- form body ----')
console.log(req.body)
}
}
module.exports = {registerUser}
When I submit my form to this route then control moves to UserController and I validations fails then I want to send it back to view without defining the redirect path I just want to send it back to view from where request received with errors. But I did not find any useful solution yet.
Is there any idea that how I can achieve this target. Suggest any useful link for nodejs beginner.
use res.send(errors) it send errors to client at this route. but if you want to redirect it to another route and then send it to client you have to create /signup route and use res.send(errors) it send errors to client. by default ``` res```` will redirect to redirected route.
router.post('/signup', (req, res)=>{
//send error or do somethings.
res.json(req.body.errors);
})
Use
app.locals.errors=errors
to make your error variable available to your template upon redirection as a general guide. Read more at http://expressjs.com/en/5x/api.html#app.locals. Remember, this will share the error variable across the application, so do not forget to apply logic that allows only the logged in user to view the error information relevant to that user.
I am turning around in stackoverflow without finding an answer to my question. I have used expressJS fur several days in order to make an access webpage that returns first an interstitial and then a webpage depending on several informations I can get from the requester IP and so on.
My first idea for the interstitial was to use this piece of code:
var interstitial = function(req, res, next) {
res.render('interstitial');
next();
}
router.get('/', interstitial, nextPage);
setting a timeout on the next nextPage callback function of router.get().
However it looks that I could not do that. I had an error "Error: Can't set headers after they are sent.". I suppose this is due to the fact that res.render already give a response to the request and in the philosophy of express, the next function is passing the req, res args for another reply to another function that possibly could do it. Am I right?
In that case, is there a way to give several answer, with timeout to one request? (a res.render, and after that in the next callback a rest.send...).
Or is this mandatory to force client to ask a request to give back another response? (using js on the client side for instance, or timers on client side, or maybe discussing with client script using socket.io).
Thanks
Not sure I fully understand, but you should be placing all your deterministic logic within the function of the handler you're using for your endpoint.
Kinda like so:
router.get('/', function(req, res){
var origin = request.origin;
if (origin == '11.22.33.44'){
res.send('Interstitial Page.');
}else{
res.send('Home Page');
}
});
You would replace the simple text responses with your actual pages, but the general idea is that once that endpoint is handled you can't next() it to secondary handler.
Inexperienced with nodejs style programming, I'm looking at an open-source node.js app that has routes with the same paths in both the front-end main.js file and the routes.js file, as you see below. I'm assuming that when the function in main.js file gets called it triggers the route in routes.js, however, I can't figure out what if anything is getting passed from main.js to routes.js as a callback.
main.js
$.get('/ip', function (data) {
fp.val(fingerprint);
userId.val(md5(fingerprint + data.ip));
});
routes.js
app.get('/ip', function (req, res) {
res.json({
ip: req.connection.remoteAddress
});
});
There's nothing node-specific about the frontend script, it's just using jQuery.get to get the document at a given URL.
On the server-side, it looks like the app is using Express (or something like it) which modifies the .send() method of the response to allow sending arbitrary objects. When you send and object, Express JSON encodes it (using JSON.stringify(object) and sets the Content-Type header of the response to application/json. This content-type header is what tells jQuery to automatically parse the JSON response back into an object in the browser.
So there is no callback being passed from main.js to routes.js, it's just a bog-standard web request that sends JSON data back to the client.
So I've seen TJ's guide to creating modular Express-apps, followed it to good effects, but want to know more about the details of how it works, however a search gives me no answers.
In short I am wondering: When mounting apps in Express, what parts of the apps are shared and what parts are not?
Some examples to clarify my question:
app.js:
app.use(express.bodyParser());
app.use(loginApi); //loginApi is an express app
app.listen(3000);
This example works. But if I place the app.use(loginApi) before app.use(express.bodyParser()); , the body parser will not be available in the loginApi subapp. Why is that?
Another example:
submodule.js
var app = module.exports = require('express')();
app.all('*', function(req, res, next){
console.log('nifty middleware');
next();
});
app.js
app.get('/funtimes', fn);
app.use(submodule);
app.listen(3000);
Now in this example, If I understand it correctly, the /funtimes route will not be affected by the submodule middleware for all routes. But what about the rest of the routes of app.js ? Will they be affected? And what if I add another module, will it be affected?
if I place the app.use(loginApi) before app.use(express.bodyParser()); , the body parser will not be available in the loginApi subapp. Why is that?
That's because of the way Express handles requests. Any incoming request starts at the top of the middleware stack, starting with app.use() stack.
Middleware are simply functions that have the function signature function(req, res, next) which either call next() if they want to hand off the request to subsequent functions, or send a response themselves. You define a 'middleware chain' of a bunch of these functions (many are provided by express, like express.logger() and express.compress().)
So in the following scenario:
app.use(express.bodyParser());
var loginApi = require('./api/index.js')
app.use(loginApi);
app.use(app.router);
then an incoming request will first hit app.use(express.bodyParser()), parsing req.body. Then that function calls its internal next(), passing it to the next function in the middleware chain (app.use(loginApi)). The loginApi app has its own middleware chain, but the requests already have req.body set from the outer app. If the loginApi doesn't send a response, the request will continue to app.use(app.router) and at that point the requests will go to the routing functions you set up in your outer app.
So the answer is: A mounted app will have the middleware functions shared, which are placed before the line app.use(loginApi)
Middleware runs in order (until one of the middlewares doesn't call next()).
If you use() your mounted app before use()ing bodyParser, the entire sub-app will run before bodyParser adds its properties.
What you're asking about is middleware. This confused me for a while. Middleware are the functions that run in order to take a request in and serve back a response. app.use() takes a function as its only argument. That function manipulates the request in a consistent way.
app.use is a lot like app.all("*").
The order matters. For example, you might want to run a validator before serving the response.
One thing I learned recently is that you can pass an array of middleware functions to a route. For example
app.get("/whatever",[
function(req,res,next}{
...validation...
next();
},
function(req,res) {
...actions....
res.send(200);
}
]);
The next callback tells express to run the next function in the middleware. Middleware can also modify the request object. This is used a lot in authentication. For example, you'll see req.user getting defined from the database so in later middleware you'll be able to refer to properties of the user. But, it can also be used for a ton of other stuff.
How does one get the response of an express app as a string given a request object?
In other words, I want a way to send a request object to an express app and receive its response as a string.
As code, I am looking for some implementation of the sendToThisApp method:
var app = express();
app.get( /* Some code here */ );
var request = // Some request object
var response = app.sendToThisApp(req)
console.log(response);
Thanks.
Here is the code for a simple Node.js Express app :
var app, express;
express = require('express');
app = express();
app.get('/', function(req, res) {
console.log(res);
res.end();
});
app.listen(8080);
In order to trigger a get request on this app, you need to run the app on node. Open a terminal and type this command:
node app.js
Then, you only need to start your favorite browser, go to localhost:8080, and look back at the log of the response in your terminal.
It looks like you're expecting things to happen synchronously that node and express want to handle asynchronously through callbacks.
But aside from that, I'm not really understanding what you're trying to do.
If you have the code for the node app, and you just want to see the response object as a string, then the easiest way to handle that is through the callback on the get.
app.get('/', function(req,res){
console.log(res);
}
But without knowing what you're actually after, I can't give better advice.