When I use foo function declaration in app.use as a middleware the compiler doesn't seem to recognize the req, res, next variables:
var express = require('express');
var path = require('path');
var app = express();
function foo (req, res, next){ // the middleware
console.log(req.path);
}
app.use('/', foo(req, res, next)); //ReferenceError: req is not defined
app.use('/', express.static("./public"));
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
By comparison if I use function declaration inside app.use the code works as intended:
var express = require('express');
var path = require('path');
var app = express();
app.use('/', function(req, res, next){
console.log(req.path);
}); //ReferenceError: req is not defined
app.use('/', express.static("./public"));
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
My understanding is not enough to see why this is an error
In your example, app.use('/', foo(req, res, next)); is calling the function and executing it as it parses through the JS file.
The other 'comparison', is a function declaration which isn't called while parsing through the file.
You can change the code to: app.use('/', foo); and it'll work properly.
Related
I am following this video to create a simple server in NodeJS (v16.19.0) and ExpressJS (v4.18.2).
app.js
const express = require("express");
const app = express();
// Middleware
const middleware = (req, res, next) => {
console.log(`Hello my middleware`);
next(); //error on this line: next is not a function
}
middleware();
app.get("/", (req, res) => {
res.send(`Hello world from server`);
});
app.listen(3000, () => {
console.log("server runnin at port 3000");
});
error: next is not a function, when I run app.js. How do I solve this
The error you're encountering is because the middleware function you've defined is being invoked as a regular function, rather than being used as middleware in an Express route. The next function is provided by Express and allows you to pass control to the next middleware function or route handler in the chain.
To use the middleware function, you need to attach it to an Express route as follows:
const express = require("express");
const app = express();
// Middleware
const middleware = (req, res, next) => {
console.log(`Hello my middleware`);
next();
};
app.use(middleware);
app.get("/", (req, res) => {
res.send(`Hello world from server`);
});
app.listen(3000, () => {
console.log("server runnin at port 3000");
});
Why does console.log('First Log') run 4 times per request?
//app.js
const express = require('express');
var app = express();
app.use((req, res, next) => {
console.log('First Log'); // problem is here
next();
});
app.use((req, res, next) => {
res.send('first response from express');
});
module.exports = app;
//server.js
const http = require('http');
const app = require('./backend/app');
var port = process.env.PORT || 3000;
app.set('port', port);
var server = http.createServer(app);
server.listen(port);
Output:
First Log
First Log
First Log
First Log
Middleware can be generic to all paths, or triggered only on specific path(s) your server handles. Below is an example of middleware declaration.
var app = express();
app.use(function () {}) //added to all paths or globally
app.get('/someroute', function() {}) //added to a specific path
Ref:
https://medium.com/#agoiabeladeyemi/a-simple-explanation-of-express-middleware-c68ea839f498
Answer mentioned in the comment by #AikonMogwai is also correct:
The middleware works one time for each url(of the same route path): index.html, favicon.ico, *.css, etc.
Change console.log to console.log(req.url) to see that.
Lets say I want to have 2 different instances in "subfolders" in the url. In app js I have it defined like this:
var routes = require('./routes/index');
app.use('/myapp1', routes);
app.use('/myapp2', routes);
The inner routing would be the same.
But still in the router I want to "get" the path defined in the app.use - eg.: myapp1, myapp2
How do I get this in the router?
From routes/index.js:
router.use(/\/.*/, function (req, res, next) {
// want to see "myapp1/myapp2" without the *sub* path defined in this particular router eg.: /products /user etc.
next();
});
You might want to use the req.baseUrl property.
Example:
routes.get('/1', function(req, res) {
res.send([
req.baseUrl,
req.path,
req.baseUrl + req.path,
].join('\n'));
});
app.use('/api', routes);
Making an HTTP request to /api/1 would print:
/api
/1
/api/1
var express = require('express');
var app = express();
var router = express.Router();
app.use(function(req, res, next) {
req.appInstance = (req.url.indexOf('/app2/') == 0) ? 2 : 1;
next();
});
app.get('/', function(req, res, next) {
res.redirect('/app1/user');
});
router.get('/user', function(req, res, next) {
res.send(req.url +' on app' + req.appInstance);
});
app.use('/app1', router);
app.use('/app2', router);
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
I'm having a problem routing in express 4. I was following the example, but it isn't loading. I'm just getting a spinning wheel.
How do you do routing in express version 4?
app.js:
var express = require('express');
var http = require('http');
var app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
var port = (process.env.PORT || process.env.VCAP_APP_PORT || 5000);
app.use('/birds', require('./controller/bird'));
http.createServer(function (req, res) {
//res.writeHead(200, {'Content-Type': 'text/plain'});
//res.end('Hello World!\n');
}).listen(port);
console.log('Server running at http://127.0.0.1:'+port);
bird.js:
var express = require('express');
var router = express.Router();
// middleware specific to this router
router.use(function timeLog(req, res, next) {
console.log('Time: ', Date.now());
next();
});
// define the home page route
router.get('/', function(req, res) {
res.send('Birds home page');
});
// define the about route
router.get('/about', function(req, res) {
res.send('About birds');
});
module.exports = router;
You're not calling the app.listen() function. Instead of the http.createServer one, you should invoke the Express function.
Please, take a look at a basic example.
Relevant code:
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
Edit: as slebetman wrote in the comment, the more general way for it is:
http.createServer(app).listen(port, function(){
console.log('now listening on port ' + port);
});
I have my nodeapp and an external route file.
I am trying to pass the object clientMap to the external router
When i try to pass using syntax from examples
app.use('/api', apiRoutes)(clientMap);
i always get the error
node_modules\express\lib\router\index.js:140 var search = 1 +
req.url.indexOf('?');
TypeError: Cannot call method 'indexOf' of undefined
at Function.handle
This is how i have it currently(just snippets cause this is a big app), which does not work
app.js
var app = express();
var http = require('http').Server(app);
var apiRoutes = require('./routes/apiRoutes');
app.use('/api', apiRoutes)(clientMap);
apiRoutes.js
module.exports = (function (clientMap) {
var router = express.Router();
router.use(function (req, res, next) {
});
router.get('/userlist', function (req, res, next) {
});
return router;
})();
I have also tried and get the same error
app.use('/api', apiRoutes(clientMap));
You should be passing to apiRoutes, not app.use:
app.use('/api', apiRoutes(clientMap));
You also want to be exporting a function as apiRoutes, not calling it as an IIFE:
module.exports = function (clientMap) {
var router = express.Router();
router.use(function (req, res, next) {
});
router.get('/userlist', function (req, res, next) {
});
return router;
};