Simple configurable Express middleware not executing - node.js

I'm trying to build a configurable middleware (a custom middleware function that takes custom parameters, and returns a (req,res,next) function that uses these parameters) in Express. However, I can't get this middleware to execute on a router.get() call.
The expected behaviour in the code below is that, when trying to GET the home page (/), the console logs 'success!' then I get a 404 (as the next() in the middleware will pass me on to the 404 function).
However, nothing happens and the request times out. The function is being detected, as when I put the console.log() in the middleware but just before the return function(req,res,next){ line, I am seeing the output on the console. I only get this issue when the configurable middleware is returning a function.
./app.js (no changes to the template that Express builds):
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
./routes/index.js:
var express = require('express');
var router = express.Router();
var simplemiddleware = require('../middlewares/simplemiddleware');
/* GET home page. */
router.get('/', function(req, res, next) {
simplemiddleware.simpleReturn('success!');
});
module.exports = router;
./middlewares/simplemiddleware.js:
exports.simpleReturn = function (outputString){
return function (req,res,next) {
console.log(outputString);
next();
}
}

Please note that the
var simplemiddleware = require('../middlewares/simplemiddleware');
actually is a function, to fix the problem, please try the following.
./routes/index.js:
var simplemiddleware = require('../middlewares/simplemiddleware');
/* GET home page. */
router.get('/', function(req, res, next) {
// note `simplemiddleware.simpleReturn(str)` returns a function
let func = simplemiddleware.simpleReturn('success!');
// run the middleware
func(req, res, next);
});

Related

Express req.query works fine with GET but not with POST

I'm using nodejs with express and trying to use query parameters. For some reason they work fine with GET but don't work at all with POST.
Here is my route file:
var express = require('express');
var router = express.Router();
router.get('/get', function (req, res, next) {
var schemaId = req.query.schemaId;
console.log("GET: "+schemaId);
});
router.post('/add', function (req, res, next) {
var schemaId = req.query.schemaId;
console.log("ADD: "+schemaId);
});
and here is the app.js itself:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const dotenv = require('dotenv');
if (process.env.NODE_ENV !== 'production') {
dotenv.config();
}
var indexRouter = require('./routes/index');
var schemasRouter = require('./routes/schemas');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/schemas',schemasRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
so doing localhost:3000/schemas/get?schemaId=test works just fine. "GET: test" is printed.
but doing localhost:3000/schemas/add?schemaId=test doesn't print anything in the console.
Seems like a super simple thing and all the examples I have seen successfully use res.query with POST.
but doing localhost:3000/schemas/add?schemaId=test doesn't print anything
Making a request via the browser's URL will always send a GET request and never a POST request.
Either write a test html page like this:
<html><script>
fetch(url, {method: 'POST'})
.then(res => res.text())
.then(res => document.body.innerHTML += res);
</script></html>
Or use something like Postman
This ..
app.use('/schemas',schemasRouter);
And This ...
var schemasRouter = require('./routes/schemas');
So maybe... This ?
localhost:3000/routes/schemas/add?schemaId=test

How to get data in express js

For the first time ever i am trying to understand expressJs and I have testing route which returns simple test sentence as JSON, but i can't get in in expressJs.
test.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('https://mysite.ccc/api/test', function(req, res, next) {
res.json(data)
});
module.exports = router;
apps.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var testRouter = require('./routes/test'); ////////////////////////////////////////////////////////here
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/test', testRouter); ////////////////////////////////////////////////////////here
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
I'm not sure but i guess it suppose to show my api sentence in http://127.0.0.1:3000/test instead with:
this command: set DEBUG=myapp:* & npm start it says: 404 not found
and with this command npm start it says request is not defined
what did i do wrong?
๐Ÿ‘จโ€๐Ÿซ You can change your test.js with this code below: ๐Ÿ‘‡
var express = require('express');
var router = express.Router();
var axios = require('axios');
/* GET home page. */
router.get('/', async function(req, res, next) {
try {
const response = await axios.get('https://mysite.ccc/api/test');
console.log(response.data);
res.json(response.data)
}catch(ex) {
console.log(ex)
res.status(400).send(ex.message);
}
});
module.exports = router;
I hope it's can help ๐Ÿ™.
Your test.js file should look like this
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
// I don't see where you defined data, should be smth like: const data = {};
res.json(data);
});
module.exports = router;
Here you define your route, so when you start your app you are able to access the route http://127.0.0.1:3000/test.
You probably want to retrieve data from external website? For this you can use any http package, for example axios.
Your final test.js file will look like:
var express = require('express');
var router = express.Router();
var axios = require('axios');
/* GET home page. */
router.get('/', async function(req, res, next) {
const response = await axios.get('https://mysite.ccc/api/test');
res.json(response.data);
});
module.exports = router;
Note: I hope you somewhere call app.listen(3000) to start your web server.

How do I correctly import Express route modules?

I generated a project with express-generator.
In my routes directory, i have 2 files : index.js and users.js, and about.js that handles the /about route.
Accessing /about results in Error 404 : Page Not found.
When adding the handler for /about in app.js, the error was gone.
./app.js:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index')
var aboutRouter = require('./routes/about');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/about', aboutRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development\
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
./route/index.js:
var express = require('express');
var app = express();
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.json( {
message : "Home Page (Requeste for list)",
method : req.method,
Succes : "True"
});
// res.render('index', { title: 'Express' });
})
module.exports = router;
./routes/about.js:
var express = require('express');
var router = express.Router();
router.get('/about', function(req, res) {
res.send('im the about page!');
});
router.post('/about', function(req, res) {
res.send('im the about page!');
});
module.exports = router;
Rewrite your router/about.js like this
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.send('im the about page!');
});
router.post('/', function(req, res) {
res.send('im the about page!');
});
module.exports = router;
Since in your app.js, you already declare the prefix /about at line 24, so you do not have to do it again in router/about.js
What is happening is that in app.js you have set the root for about rout as "/about" and inside "about.js" you have specified router.get('/about') again, what will result in, for accessing the about route having to use /about/about (you may try before fix it). For you to get the result that you are expecting you should use router.get(ยด/ยด) inside about.js and in app.js keep as it is app.use('/about', aboutRouter);. You can have a look at https://expressjs.com/en/guide/routing.html for more information. Regards.

How to debug 404 error in Nodejs web application?

I am working on a Nodejs Web application project which is based on Express Framework. I am working on creating a Sign up page. After giving the username and password the url should be redirected to profile page. In the views folder I created a file "profile.hbs". But the profile is not being recognized and I getting 404 not found. Please share your ideas on how to debug this issue.Thanks in advance.
app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var expressHbs=require('express-handlebars');
var mongoose=require('mongoose');
var session=require('express-session');
var passport=require('passport');
var flash=require('connect-flash');
const mocha=require('mocha');
var validator=require('express-validator');
var indexRouter = require('./routes/index');
//var usersRouter = require('./routes/users');
var app = express();
mongoose.connect('mongodb://localhost:27017/shopping');
require('./config/passport');
// view engine setup
app.engine('.hbs',expressHbs({defaultLayout:'layout',extname:'.hbs'}));
app.set('view engine', '.hbs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(validator());
app.use(cookieParser());
app.use(session({secret:'mysupersecret',resave:false,saveUninitialized:false}));
app.use(passport.initialize());
app.use(flash());
app.use(passport.session());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
//app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Routing file
var express = require('express');
var router = express.Router();
var csrf=require('csurf');
var passport=require('passport');
const canine= require('../models/dogfood');
var csrfProtection=csrf();
router.use(csrfProtection);
/* GET home page. */
router.get('/', function(req, res, next) {
canine.find(function(err,docs){
var productChunks=[];
var chunkSize=3;
for(var i=0;i<docs.length;i += chunkSize){
productChunks.push(docs.slice(i,i+chunkSize));
}
res.render('shop/index', { title: 'Express',diets:productChunks});
});
});
router.get('/user/signup',function(req,res,next){
res.render('user/signup',{csrfToken:req.csrfToken()})
});
router.post('user/signup',passport.authenticate('local.signup',{
successRedirect:'user/profile',
failureRedirect:'user/signup',
failureFlash:true
}));
router.get('user/profile',function(req,res,next) {
res.render('user/profile');
});
module.exports = router;
Apart from adding a view file you should also add a new route which renders that view
app.get('/', function (req, res) {
res.render('profile.hbs', {
title: 'Profile',
// and any extra data you need, probably coming from your auth middleware
});
});

Express: How can I handle this? (About `Route`)

I am beginner at node.js and express.
In my example project, firstly, I made an express project.
And I want to add a page named /product.
So, I take these steps.
Add product.jade file at views folder.
Add product.js file at routes folder.
revise app.js.
The product.jade is like this.
extends layout
block content
h1 #{title}
p Product Info.
The product.js is like this.
var express = require('express');
var router = express.Router();
/* GET product info. */
router.get('/product', function(req, res, next) {
res.render('product', { title: 'Express' });
});
module.exports = router;
Finally, I revised app.js. I added two lines.
One isvar productRouter = require('./routes/product');,
and the other is app.use('/product', productRouter);.
I was expecting it works.
But when I enter at localhost:3000/product, I only can see 404, Not Found.
Please help. What am I missing?
--- EDIT ---
app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var productRouter = require('./routes/product');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/product', productRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
You created a route for /product/product because your middleware specifies /product with this line:
app.use('/product', productRouter);
And, then your route again specifies /product in addition to that with this line:
router.get('/product', function(req, res, next) {...}
That creates a route for /product/product.
There are a couple ways to fix this. If your intention is that the productRouter handles all routes that start with /product, then leave the app.use() the same and change from this:
router.get('/product', function(req, res, next) {...}
to this:
router.get('/', function(req, res, next) {...}
If you don't intend to have multiple routes that start with /product and only need to define the one /product route handler, then you don't need to create a whole separate router just for that. You could instead, just export the route handler from product.js (instead of exporting the router) and then just use:
app.get('/product', require('./routes/product'));
That would put just a single route handler in product.js and avoid creating a router for just one route.

Resources