I'm working on my side structure and tried to add multiple single pages.
Here is my site structure:
bin
node_modules
public
query
routes
- index.js
views
-menu
--menu1.ejs
--menu2.ejs
--menu3.ejs
-partials
--header.ejs
-index.js
-anzeige.js
-eintragen.js
I tried to route the sites in my index.js like this:
//works
router.get('/', (req, res) => {
console.log('Request for index recieved');
res.render('index');
});
//works
router.get('/menu1', (req, res) => {
console.log('Request for menu1 page recieved');
res.render('menu/menu1');
});
//not working
router.get('/menu2', (req, res) => {
console.log('Request for menu2 page recieved');
res.render('menu/menu2');
});
//not working
router.get('/menu3', (req, res) => {
console.log('Request for menu3 page recieved');
res.render('menu/menu3');
});
//works
router.get('/anzeige', (req, res) => {
console.log('Request for anzeige page recieved');
res.render('anzeige');
});
I also added index.js to my app.js as a route but somehow my console says me that menu2 and menu3 can't be found (error 500 internal server error).
Request for menu2 page recieved
GET /menu2 500 7.958 ms - 305
GET http://localhost:3000/menu2 500 (Internal Server Error)
Additionally my app.js, which first creates const routes and implents it afterwards with app.use('/', routes);
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
//Place routes here
//var indexRouter = require('./routes/index');
const routes = require('./routes');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
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')));
//add routes here
app.use('/', routes);
// 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;
menu2.ejs
<!DOCTYPE html>
<html lang="de">
<head>
<title>Speiseplan anzeige</title>
<%- include('partials/header') %>
</head>
<body class="mainContainer">
<div class="midContainer">
<h1>menu2</h1>
</div>
</body>
</html>
Am I missing something? It's a bit strange that some sites work and some not.
Problem found - here the soultion for everyone with the some problem.
As Rajan mentioned I should use ../partials/header instead of partials/header.
This worked for me and everything is now displayed perfectly.
Thank you all!
Related
I am setting up a site on Express.JS with express-generator but ran into a hiccup with the routing. Currently I keep receiving the "error" view and a 404 message whenever sending a GET request to another route I set up ("/hook"). Currently the two routes that are working is "/" which goes to the "index" and "/users" which goes responds a message. I would like to see why I am getting this error as the others work.
Here is the app.js file:
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 hookRouter = require("./routes/hook");
var app = express();
// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
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("/hook", hookRouter);
// 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;
Here is the index router
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
Here is the hook router:
var express = require("express");
var router = express.Router();
/* GET hook page. */
router.get("/hook", function (req, res) {
res.send("Hook Page Works");
});
module.exports = router;
Please let me know there is any more info I can give. Thanks!
The hook router needs to be:
/* GET hook page. */
router.get("/", function (req, res) {
res.send("Hook Page Works");
});
This:
app.use("/hook", hookRouter);
has already used the /hook part of the path so within the router, you just want /.
Your original combination of:
app.use("/hook", hookRouter);
router.get("/hook", ...);
will respond to the URL /hook/hook.
I have Node.js, Express and Pug installed, and thought I was doing an MVC application. However, while I want my frontend pages to be (home, about, contact, login) with (snippets of data to connect to the backend) I can create these with pug (under views).
Wouldn't it be much faster to do these pages as static under my public folder with a stylesheet attached? Of course, I believe they would then need to be compiled into HTML for these to work I.
All I want to be able to do is create navigation that links these pages simply in pug, however, when running NPM I keep getting 404 errors (despite it working this morning).
If I can do this easily with pug, and just put a link, then why am I creating routes on the backend? Can someone please clarify this?
Pug (Sep nav file)
nav
a(href="/") Home
a(href="about") Framework
a(href="contact") Pricing
a(href="login") Support
Express Routes
app.get("/about", (req, res) => {
res.render("about");
});
app.get("/contact", (req, res) => {
res.render("contact");
});
app.get("/login", (req, res) => {
res.render("login");
});
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 app = express();
// View Engine ----------------------------
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')));
// Routes
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.get("/about", (req, res) => {
res.render("about");
});
app.get("/contact", (req, res) => {
res.render("contact");
});
app.get("/login", (req, res) => {
res.render("login");
});
// 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've used Django before and despite its MVT (its very similar) but a lot simpler I think and I was able to do e.g %link% to insert it into the HTML page.
I have this about.js route and it works fine but I don't understand how / in router.get() would work while /about wouldn't?
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('about', { title: 'About' });
});
module.exports = router;
----------------- UPDATE ----------------------
It's basically what I got out of the box after installing express.js
except the about lines.
I expected router.get('/about' ...) in about.js would work but it threw an error and it worked with / instead and that's what bugs me.
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var about = require('./routes/about');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/about', about);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
The problem
When you define a route on your app.js as you did with app.use('/about', about);. You are already telling express that you expect requests to hit http://yourserver/about route.
If you try to define /about again inside your about.js with:
router.get('/', function(req, res, next) {
res.render('about', { title: 'About' });
});
What you're doing is tellig the Express that you will hit a /about inside your firstly declared /about. So it will expect requests on this route: http://yourserver/about/about
The solution
It's actually what you're using. Define a root route inside your about.js as:
router.get('/', function(req, res, next) {
res.render('about', { title: 'About' });
});
This way your app will be:
Modular since you're using different files for different routes (about.js, users.js)
Easier to read
With simplier routes inside each file, since you don't need to type /about everytime you wish to create a new route.
If you wish a http://yourserver/about/help simply add a handler inside your route file about.js as here:
router.get('/help', function(req, res, next) {
res.render('help', { title: 'Help' });
});
If you want the route /about work then you have to create another route:
router.get('/about', function(req, res, next) {
res.render('about-page', { title: 'About' });
});
because / will only work for the home page.
I am trying to create two separate routes in NodeJS, I am using the express framework and angular on the client side. I am currently able to render my index page successfully by visiting localhost:3000/ although when I try to render the login page by visiting localhost:3000/login I am getting a GET /login 404 error and not sure why b/c I set it up extremely similar to the index route. Not sure if I missed something.
This my app.js
//require dependencies
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
//require routes but do not user yet
var routes = require('./routes/index');
var login = require('./routes/login');
//start app
var app = express();
// view engine setup - default views directory
app.set('views', path.join(__dirname, 'views'));
app.locals.delimiters = '<% %>';
app.set('view engine', 'hjs'); //use hogan templating for views
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(require('less-middleware')(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/login', login);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
routes/login.js
var express = require('express');
var router = express.Router();
router.get('/login', function(req, res){
res.render('login');
});
module.exports = router;
views/login.hjs
<!DOCTYPE html>
<html>
<head>
</head>
<body>
HELLO WORLD
</body>
</html>
Visiting localhost:3000/login renders the following:
{{ message }}
{{ error.status }}
{{ error.stack }}
When writing app.use('/login', login), you are telling Express to use your router under the namespace : '/login'; Therefore, all routes defined into login.js don't need this prefix.
Try to access localhost:3000/login/login ;)
Then, just change your router to:
router.get('/', function(req, res){
res.render('login');
});
Though I have read quite a few questions being answered on stackoverflow, I'm still unable to get it to work even after a couple of days of trying. It's my first week with express and node and so I don't know if I'm doing the small things right. I basically want to upload a file and later on save it to the file system, however, I'm unable to proceed with req.files giving me undefined. Please see my code below.
This is my app.js
var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var routes = require('./routes/index');
var users = require('./routes/users');
var upload = require('./routes/upload.js');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/upload', upload);
/// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
/// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
This is my routes/upload.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
console.log("");
console.log(req.files);
res.send('this is the page you get upon doing file upload');
});
module.exports = router;
This is my views/homepage.jade
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
p select file to upload
form(action="upload", method="get", enctype="multipart/form-data")
input(type="file", name="displayImage")
input(type="submit")
At the moment, I'm hearing a lot of terms like multer, connect-busboy, bodyParser being deprecated from express4 etc but with no real idea on how to proceed. Please advise me on how I can proceed and what code should be added.
Thanks.
You need a middleware module that can parse your uploaded file.
Like such:
https://github.com/expressjs/multer
https://github.com/mscdex/connect-busboy
Then use the middleware in your index.js, like:
app.use(multer({ dest: './uploads/'}))
or
app.use(busboy());
A number of modules were removed from Express in 4.0 and are now separate packages you have to include. The easiest way to get started with it is to use express-generator to generate the scaffolding for you. This will include and require the correct packages for parsing cookies, and the request body. It doesn't include a file parser however. I put together an example using multer and put it on Github for you to reference.
After you clone it, you can run npm install, and then npm start.
One other thing you were doing incorrectly that I fixed was using app.get for your upload handler. You can't use GET to upload a file. In my example I changed this to a POST request. Here are the relevant snippets.
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var multer = require('multer');
var routes = require('./routes/index');
var users = require('./routes/users');
var upload = require('./routes/upload');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(multer({ dest: './uploads/'}))
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/upload', upload);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
index.jade
extends layout
block content
h1= title
p select file to upload
form(action='upload', method='post', enctype='multipart/form-data')
input(type='file', name='displayImage')
input(type='submit')