I'm relatively new to Express and Node but this seems like a VERY basic demand and I am struggling to understand how it could be happening. Any help in solving the problem or identifying how I'd troubleshoot it would be VERY appreciated.
Problem
var
express = require('express'),
bodyParser = require('body-parser'),
logger = require('morgan'),
express = require('express'),
app = express();
app.get('/heartbeat', function(req,res) {
res.status(200).json(req.header('host'));
});
// my simple middleware component
app.use(function (req, res, next) {
console.log('made it');
next();
});
// standard middleware components
app.use(logger('dev'));
app.use(bodyParser.urlencoded({ extended: true }));
// Start listener
app.listen(4400);
This simple program does output my "made it" console message but yet when I wrap all the code (minus the variable definitions) in a function called start:
var
express = require('express'),
bodyParser = require('body-parser'),
logger = require('morgan'),
express = require('express'),
app = express();
var start = function(config) { ... }
exports.start = start;
and then call start from a separate module I find that the logging and bodyParser modules seem to execute but my middleware component is ignored. I'm pulling my hair out trying to figure why.
I see 2 issues with your code:
You must call app.use() before calling app.get(...) Otherwise, none of the middlewares are called.
In your custom middleware, you need to call next() or next(error) so that the request is moved to the next middleware. Otherwise, your server hangs forever.
If you post your whole code after separating module, I can help you find more issues :)
Related
I have set up my code in server.js which worked fine. I am now trying to clean up the server.js code by splitting the code into different routes.
I am using the express.Router to link up the files but i am struggling to understand why my post route is braking.
In the server.js file
// dependencies
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyparser.urlencoded({extended: true}));
app.set('view engine', 'ejs');
// routes
constpurchaseOrders = require("./routes/purchaseOrders");
app.use("/purchaseOrders", purchaseOrders);
// listen
app.listen(3000, function(){
console.log("Server started on port 3000");
});
In the purchaseOrders.js file
// dependencies
const express = require("express");
let router = express.Router();
const mongoose = require("Mongoose");
const connection = require("../routes/mongoose.js");
const Po = require("../routes/schemas.js:);
// post route
router.post("/addpo, function(req.res){
//long code lines here
po.save();
res.redirect("/");
});
module.exports = router;
So with this route, i have the following end point on the route.get:
10.0.0.15:3000/purchaseOrders/addpo
Now the problem comes in when i submit the form, it returns "cannot POST /addpo" and the end point shows:
10.0.0.15:3000/addpo
On my ejs file i have set the form up as follows:
<form action="/addpo" method="post">
On the mongoose.js connection i export as follows:
module.exports = mongoose;
On the schemas.js i export:
module.exports = Po;
I know I did something wrong with the routing but i cannot figure our why.
Thanks alot :-)
if you need the /addpo path to work, change this on server.js:
app.use("/", purchaseOrders);
NOT
app.use("/purchaseOrders", purchaseOrders);
Other option
server.js:
app.use("/addpo", purchaseOrders);
purchaseOrders.js
router.post("/", function(req.res){
If you add a route before calling a router it will be added in front of it.
So, yo can use the route action="/addpo" in the html.
Express docs
As mentioned in express routing guide and this answer, we can create "mini-app" and use it from the main app. However I saw a code where it uses app instead of router in the module
app.js
var express = require('express');
var userRoutes = require('./routes/user');
var app = express();
app.use('/user', userRoutes);
module.exports = app;
routes/user.js
var express = require('express');
var app = express(); // not express.Router() !!
app.get('/:name', function(req, res) {
var userName = req.params.name;
res.render('user.jade', {
userName: userName
});
});
module.exports = app;
I assumed the correct usage in routes/user.js should be
router = express.Router()
instead of
app = express()
but app = express() also works! what are the differences and why router = express.Router() is better?
When you are working with a server where there are many routes, it can be confusing to leave them in a Main file together. The let router = express.Router() option works differently than let app = express().
While the app returns an app object, router will return a small app fragment, similar to the app, where you will use logic to call them later on the Main.
The most important, about your question, is that a router, which is isolated, will not interfere with others in the application, being a single environment.
https://expressjs.com/en/api.html#router
A router object is an isolated instance of middleware and routes. You can think of it as a “mini-application,” capable only of performing middleware and routing functions. Every Express application has a built-in app router.
A router behaves like middleware itself, so you can use it as an argument to app.use() or as the argument to another router’s use() method.
(I know that there is a similar question in stackoverflow, but I can't understand that question's comment..)
I'm Korean middle schooler.
So I am not good at English but Please help me.
I'm studying Node.js and Express.js by example codes.
This is example code which I'm looking at.
var express = require("express");
var app = express();
var bodyParser = require("body-parser");
var session = require("express-session");
var fs = require("fs");
app.set("views", __dirname + "/views");
app.set("view engine", "ejs");
app.engine("html", require("ejs").renderFile);
var server = app.listen(3000, function() {
console.log("Express server has started on port 3000");
});
app.use(express.static("public"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(session({
secret: '##SEC$$RET##',
resave: false,
saveUninitialized: true
}));
var router = require("./router/main")(app, fs)
I have understood majority of this code, but I cannot understand "(app, fs)" at last line.
What does that mean??
I'll appreciate your kindness if you help me .. ㅠㅠ
This means that ./router/main module exports factory function that accepts application instance and fs module as parameters and returns router instance that depends on these parameters, e.g.:
var express = require('express');
module.exports = (app, fs) => {
var router = express.Router();
// define router routes that make use of `app` and `fs`
return router;
};
This way router factory function basically implements dependency injection pattern.
app parameter is a common Express recipe to pass application instance to a router, while passing fs is unneeded. fs module could be imported directly in ./router/main module, it doesn't benefit much from dependency injection.
It imports the router from that file. The router requires you to pass 2 parameters - the app and fs. It's the same as calling a regular function. Just here, it is importing the route and calling the function in one place.
I am playing with node.js and I don't quite understand why something I set up is working in one instance but if I make a slight change it will not work in another instance.
in my app.js I have
app.use('/musicplayer', require('./routes/music/index'));
in my music\index.js I have
var express = require('express');
var router = express.Router();
router.use('/users', require('./users'));
module.exports = router;
in my users.js I have this - working version
var express = require('express');
var usersRouter = express.Router();
var sqllite3 = require('sqlite3').verbose();
usersRouter.get('/login', function(req, res, next) {
res.render('music/login', { title: 'Express' });
});
module.exports = usersRouter;
But I would like to encapsulate the routes I am defining into another function like this not working this just hangs the page.
Modified version of my users.js not working
var express = require('express');
var usersRouter = express.Router();
var sqllite3 = require('sqlite3').verbose();
var router = function () {
usersRouter.get('/login', function (req, res, next) {
res.render('music/login', {title: 'Express'});
});
return usersRouter;
}
module.exports = router;
In the console I can see it comes in tries the get and nevers gets routed I see this "GET /musicplayer/users/login - - ms - -".
I have even put a console.log right before the return in the anonymous function I created to know it is getting in there and that I am hooking the pathways up right from the parent routes. And I do hit that log action to the screen.
Any help or tips would be appreciated:)
PS in case you are wondering I am trying to separate out apps for different development work I want to play with. So that is why I am doing the sub routing with musicplayer/index.js instead of just putting everything in the app.js for declaring of my main routes.
Router.use() expects an instance of another Router. However your (non-working) module only returns a function.
Use this in your index.js to fix the issue:
router.use('/users', require('./users')());
Dumb/Newb question...
I am learning/working on an API in Node / Express4 and I would like to break my routes out into another module. I have it working with the following code, but it seems awkward to me to keep re-using the require('express') statement... Is there a way to move more of the code from the routes.js file into server.js and still keep my .get and .post statements in the routes module? Thanks in advance!
server.js:
'use strict';
var express = require('express');
var routes = require('./routes');
var app = express();
app.use('/api', routes);
app.listen(3000, function() {
console.log('Listening);
});
routes.js
var express = require('express'); // how do I get rid of this line?
var router = express.Router(); // can I move this to server.js?
var apiRoute = router.route('');
apiRoute.get(function (req, res) {
res.send('api GET request received');
});
module.exports = router;
Your on the right track. Its actually cool to reuse the var express = require('express'); statement each time you need it. Importing, ( requiring ), modules is a cornerstone of modular development and allows you to maintain a separation of concerns with in the files of your project.
As far as modularly adding routes is concerned: The issue is that routes.js is misleading.
In order to modularly separate out your routes you should use several modules named <yourResource>.js. Those modules would contain all of the routing code as well as any other configuration or necessary functions. Then you would attach them in app.js with:
var apiRoute = router.route('/api');
apiRoute.use('/<yourResource', yourResourceRouter);
For example, if you had a resource bikes:
In app.js or even a module api.js:
var apiRoute = router.route('/api')
, bikeRoutes = require('./bikes');
apiRoute.use('/bikes', bikeRoutes);
Then in bike.js:
var express = require('express');
var router = express.Router();
var bikeRoutes = router.route('/');
bikeRoutes.get(function (req, res) {
res.send('api GET request received');
});
module.exports = bikeRoutes;
From there its easy to see that you can build many different resources and continually nest them.