I've got a node.js/express app I'm working on and routes that look like-
app.post('/user/:who/update', isLoggedIn, userUpdate.save);
inside userUpdate.save I'm calling res.redirect or res.render (different routes but same idea). I don't like this. I'd like to keep my res.* calls in routes.js, but when I attempt this
app.post('/user/:who/update', isLoggedIn, userUpdate.save, function(req, res) {
res.redirect('/user/'+req.user.local.username);
});
with a call to next(req, res) at the end of userUpdate.save, the res.redirect function isn't called. What I think next() is, does not seem to be what it actually is. What am I missing?
The call to next() bypasses the remainder of your callbacks.
See this ref http://expressjs.com/api.html#app.post.method
Take a look at this example and alternately comment out each of the next() calls (and then both of them) and watch where the execution flows.
var express = require('express');
var app = express();
app.get('/test', function(req, res, next){
console.log('/test callback1');
next('route');
//next();
}, function(res, res, next){
console.log('/test callback2');
res.send('sent from /test/cb2')
});
app.get('/test', function(req, res){
console.log('response from /test route handler 2');
res.send('sent from /test route handler 2');
})
var server = app.listen(8911, function (s) {
console.log('Listening on port ', server.address().port);
});
Related
Why I enter http://localhost:3000/product on the browser, the output will be both outputs of '/' and '/product'?
Please look at this snippet code.
const express = require('express');
const app = express();
// http://localhost:3000/product
app.use('/product', (req, res, next)=>{
console.log('In product page');
res.send('<h1>Product Page</h1>');
});
// http://localhost:3000/
app.use('/', (req, res, next)=>{
console.log('In main page');
res.send('<h1>Main Page</h1>');
});
app.listen(3000);
This image is my app's output.
It could have multiple reasons. One that I think of right now is that the browser requests http://localhost:3000/favicon.ico automatically after product.html, which triggers the use('/', ...) route.
Maybe you should use app.all(...) instead of app.use(...), to avoid this "wildcard" on every path that should rather be a 404 page.
The app.use() method is used to bind application level middleware. Not for accepting GET request as you are expecting.
You should use
// http://localhost:3000/product
app.get('/product', (req, res)=>{
console.log('In product page');
res.send('<h1>Product Page</h1>');
});
// http://localhost:3000/
app.get('/', (req, res)=>{
console.log('In main page');
res.send('<h1>Main Page</h1>');
});
Because in express whatever you define with app.use() is middleware and it always executes until and unless it has some path defined
app.use('/', (req, res, next)=>{
console.log('In main page');
res.send('<h1>Main Page</h1>');
});
above will always execute because it contains root path and every url has root path
Check this link for further info https://expressjs.com/en/4x/api.html#app.use
You should define your routing with express router using app.get("/") or app.post("/") and it will help for more info https://expressjs.com/en/guide/routing.html
I have an Angular app running alongside a NodeJS server.
This code in my server.js file:
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
require('./server/routes/routes')(app, passport);
Seems to be preventing any GET requests to my api, for example:
module.exports = function (app, passport) {
app.get('/api/profile', isLoggedIn, function (req, res) {
res.status(200).json(req.user);
});
When the exported /api/profile handler is changed to a post the request works.
Should the route not overwrite the initial handler? How to achieve this? Can I serve the app for all routes excluding beginning with '/api'?
Move the app.get('*') so it becomes the last route that gets declared:
require('./server/routes/routes')(app, passport);
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
Express checks route handlers in order of their declaration, not in order of their specificity (how well they match a particular request).
I am trying create a route, but I getting this error.
res.send is not a function
And my code in the index.js file it is this way
var express = require('express');
var router = express.Router();
router.get('/', function(res, req, next){
res.render('index');
});
module.exports = router;
And in the app.js file is that way
var index = require('./routes/index.js');
...
...
...
app.get('/', index);
Thank you, since already.
It looks like you've swapped req and res in your router.get callback. Thus, what you've named req is actually res, and vice versa, and req.render does not exist.
Try changing:
router.get('/', function(res, req, next){
to:
router.get('/', function(req, res, next){
To avoid mixing these up in the future, try to remember that requests come before responses, in both HTTP and the alphabet.
I've been trying to get this fixed for the last few hours but can't find something that works. What I'm using right now is the standard:
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
});
I've tried to use the solution someone posted in another thread:
app.get(/*./, function (req, res) {
res.sendFile(__dirname + '/index.html');
});
But this doesn't work and gives me a "Uncaught SyntaxError: Unexpected token <".
I guess that solution is based of expressjs own examples:
app.get(/*test$./, function (req, res) {
res.sendFile(__dirname + '/index.html');
});
Which works for every route that has the phrase "test" in the first level (and ONLY the first lvl '/test'=yes, '/app/test'=no.
WHAT I WANT: Since I've a react app that always returns the same html page and that handles invalid routes within the app I want to make every request to my webpage return the exact same index.html (no matter what route the user asks for, '/' --> index.html '/test/test/test/test' --> index.html and so on.
Anyone have any ideas how I can do this? I've run out of google results
Thanks in advance!
Below is my entire server as of right now:
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
app.use('/build', express.static('build'));
io.on('connection', function(socket){
console.log('Connected');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
If you just have app.use(yourStaticMiddleware), the function
"yourStaticMiddleware" will be executed for every request. If that middleware ends the response (eg by calling res.send() or res.sendFile()), then nothing after it will be called except error handlers.
this will work for every get request
app.get("*",function(req,res,next){
res.sendFile(__dirname + '/index.html');
})
Use app.all() method.
This method is used for loading middleware functions at a path for all request methods.
app.all(function (req, res, next) {
//will hit every page request regardless of http method
next(); // pass control to the next handler
});
For more you can refer exprress routing
Consider this little app:
var express = require("express");
var app = express();
app.get("/json", function(req, res){
console.log("JSON route");
res.json({foo: "bar"});
});
app.get("/", function(req, res){
console.log("Slash route");
res.send("Hello");
});
app.get("*", function(req, res){
console.log("Star route");
res.redirect("/");
});
app.listen(3000, function(){
console.log("Listening.");
});
Whenever I go to either localhost:3000 or localhost:3000/json in my browser, I can see from my server log that the star * route is also triggered. This is still true if it is changed to app.get("/*")
Why is this? I thought res.send and res.json halted execution.
When you request something with your browser, it will automagically try to request a favicon. Since your server doesn't have a route defined for a favicon, it goes to the * route, causing this confusion.