Routing folders with express in node.js - node.js

I decided to take my routes out of my app.js and into their own seperate folders but now the site will load the handlebars file for index but not for about or contact - I am very confused and require help in exchange for a +1.
// Import the express module
var express = require('express');
var path = require("path");
var bodyParser = require("body-parser");
var index = require('./routes/index');
var about = require('./routes/about');
var contact = require('./routes/contact');
var handlebars = require('express-handlebars').create({defaultLayout:'main'});
var app = express();
// Block the header from containing information
// about the server
app.disable('x-powered-by');
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'handlebars');
app.engine('handlebars', handlebars.engine);
//set static folder
app.use(express.static(__dirname + '/public'));//allows access to public directory
//set bower folder
app.use('/bower_components', express.static(__dirname + '/bower_components'));//defines bower components directory
//body parser MW
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.set('port', process.env.PORT || 1337);// Defines the port to run on
app.use("/", index);
app.use("/about", about);
app.use("/contact", contact);
app.use(function(req, res){
res.type('text/html');
res.status(404);
res.render('404');
});
app.use(function(err, req, res, next){
console.error(err.stack);
res.status(500);
res.render('500');
});
app.listen(app.get('port'), function(){
console.log("Express started on http://127.0.0.1:" + app.get('port') + ' Press Ctrl+C to terminate');
})
This is the routes/index.js file:
var express = require("express");
var router = express.Router();
// Defines the base url
router.get('/', function(req, res, next){
// Point at the home.handlebars view
res.render('home');
});
module.exports = router;
And routes/about.js
var express = require("express");
var router = express.Router();
router.get('/about', function(req, res, next){
res.render('about');
});
module.exports = router;
When I go to localhost/contact, I get my 404 page and the same for /about.
The views are located in app/views, it worked when I had them down the pipeline in the app.js but since removing them it has broken. Any suggestions would be much appreciated!

This issue was with the routing itself. Say we are looking for /about with:
app.use("/about", about);
The app will then look into the routing folder of about and find the following.
var express = require("express");
var router = express.Router();
router.get('/about', function(req, res, next){
res.render('about');
});
module.exports = router;
And since I had another /about here in the router.get this would render at localhost/about/about

Related

NodeJs routes not working from inner page

I am trying to develop an application in NodeJs using express framework. My routing is working when I navigating from home to inner pages. But If I want to navigate from some inner page to homepage then it is not working.
Below is my app.js code.
const express = require('express');
const path = require('path');
const engines = require('consolidate');
const bodyParser = require('body-parser');
//declare all routers
var home = require(path.join(__dirname, "/routes/index"));
var myaccount = require(path.join(__dirname, "/routes/myaccount"));
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.engine('html', engines.handlebars);
var defaultViewPath = path.join(__dirname, "/views");
app.set('views', defaultViewPath);
app.set('view engine', 'html');
app.use('/', home);
app.use('/myaccount', myaccount);
Here if I have navigated from home to myaccount - Its working
But if I am navigating from myaacount to home - It reloads the same page.
Can anyone help me to resolve this issue.
To define routing using methods of the Express app object, use app.get() to handle GET requests
var express = require('express')
var app = express()
// When GET request is made to the homepage
app.get('/', function (req, res) {
res.render('home');
});
// When GET request is made to the myaccount
app.get('/myaccount', function (req, res) {
res.render('myaccount');
});
app.get('/myaccount/innerpage', function (req, res) {
res.send('Hello Inner Page');
});
//Page Not Found
app.use(function(req, res){
//render the html page
//res.render('404');
res.sendStatus(404);
});
Hope this could help you
use app.get and app.post Route Methods
app.get('/',function(req,res){
res.render('home');
});
app.get('/myaccount',function(req,res){
res.render('myaccount');
});
Or Create Router File For Home & myAccount
var express = require('express')
var router = express.Router()
router.get('/', function (req, res) {
res.send('Home Page')
})
module.exports = router
in Your app.js or index.js file , require route.js
var home = require('./route');
app.use('/', home)

node.js express app can't find jade view, 404 message responded

for my app i use node.js as backend and Express as framework. I use Netbeans as IDE and i get the following output.
Not Found
404
Error: Not Found
at /home/ingeborg/netbeans/GML/app.js:33:13
at Layer.handle [as handle_request] (/home/ingeborg/netbeans/GML/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:317:13)
at /home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:335:12)
at next (/home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:275:10)
at /home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:635:15
at next (/home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:260:14)
at Function.handle (/home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:174:3)
at router (/home/ingeborg/netbeans/GML/node_modules/express/lib/router/index.js:47:12)
I have the following data setup:
- node-modules
- public
- fonts
- images
- javascripts
- stylesheets
stylesheets.less
stylesheet.css
- routes
index.js
news.js
users.js
- views
index.jade
error.jade
news.jade
layout.jade
Gruntfile.js
app.js
gulpfile.js
package.json
the app.js looks like this
var news = require('./routes/news');
var index = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
...
app.use('/', index);
app.use('/index', index);
app.use('/news', news);
app.use('/users', users);
and this is my index.jade
h3
a(href="news") link
and this my news.jade
h3 test
.
The routing is realised over route files.
index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index');
});
router.get('/index', function(req, res, next) {
res.render('index');
});
module.exports = router;
the news.js router file is
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('news', function(req, res, next) {
res.render('news');
});
module.exports = router;
The following circumstances are
the routing on the links "/" and "index" works as wanted.
the routing on "/news" or "news" (tested in the rounting, app.js and view file) not. I have no clue why the routing isn't working. I hope i haven't forgotten sth.
Thx,
Inge
Your code works for 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 index = require('./routes/index');
var news = require('./routes/news');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// 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('/', index);
app.use('/users', users);
app.use('/news', news);
// 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 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/news.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('news');
});
module.exports = router;
The news route file is missing. There you have to render your jade.
var news = require('./routes/news');

App is Running But Not Opening in Browser? It shows Page Not Available

In console it shows message that app/server is running but when I open app in browser it show page not available.
Here's my code for the server initialization (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 server = require('http').Server(app);
var io = require('socket.io')(server);
var app = express();
var viewRoute = require('./routes/view'),
apiRoute = require('./routes/api');
app.set('views', path.join(__dirname, 'views'));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
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('/', viewRoute);
app.use('/api', apiRoute);
server.listen(9190, function(){
var host = server.address().address,
port = server.address().port;
console.log("Server Running # http:%s:%s", host, port);
});
And my file with the routes (api.js):
var express = require('express');
var api = express.Router();
module.exports = (function() {
api.get('/', function(req, res, next) {
console.log("GET Request for Index Page");
});
api.get('/home', function(req, res, next) {
console.log("GET Request for Home Page");
});
return api;
})();
I've already searched google and every other resources but can't find solution.
It seems you are not sending response back to browser,
in api.js change api.get('/' code to like following:
api.get('/', function(req, res, next) {
res.send("Yes Its working now");
});
You're not sending anything back to the client, so nothing shows up in your browser. Use res.send or similar for this.
I'd suggest to change your code for something like this, and see if this works :
var express = require('express'),
app = exports = module.exports = express();
app.get('/', function (req,res) {
console.log("GET Request for Index Page");
res.send("GET / - 200");
});
app.get('/home', function (req,res) {
console.log("GET Request for home Page");
res.send("GET /home - 200");
});
I removed the exported function immediate call by the way.
I also had same issue, My server was running but i was not able to open my app on browser, Uninstalling skype worked for me.

Express 4 with Handlebars add new Route

I am trying to add an "about" page to my new express app.
I am running express 4 with handlebars (hbs).
I have read through a number of tutorials but most don't go into adding a new route (or do but don't explain very well) I have been working from this tutorial primarily.
I need to know what to add to my app.js and my routes/ folder, I have about.hbs ready in views.
here is my app.js (generated by express generator):
var express = require('express');
var path = require('path');
var favicon = require('static-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 app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
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);
/// 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;
and my routes/ folder contains index.js and users.js.
index.js:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
res.render('index', { title: 'Express' });
});
module.exports = router;
Sorry for simplicity of question, but I have spent 3 hours on this already and I feelit is probably a fairly easy thing to do.
I suggest you ditch the general default express generated application and create a proper routing system. Your app.js file should not contain routing, only environment variables. Here is the way I've setup my projects:
App.js
var express = require('express');
var http = require('http');
var path = require('path');
var compression = require('compression');
var app = module.exports = express();
var cacheTime = 86400000*7; //a week
//all environments
app.use(compression());
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.engine('html', require('hogan-express'));
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public',{ maxAge: cacheTime }));
//development only
if ('development' === app.get('env')) {
app.use(express.errorHandler());
}
require('./routes/index.js');
http.createServer(app).listen(app.get('port'), function(req,res){
console.log('Express server listening on port ' + app.get('port'));
});
The routes file:
var app = require('../app.js');
app.get('/Contact', function(req, res) {
res.render('contact.html', { /*object*/ });
});
//continue routes here
It's scalable and a viable option for large company projects. You may also split up the routes file into sepererate sections to organize better. Note: You will need to change some of my settings to your liking

how do i fix routes to find views inside subfolders in node.js

i am trying to create a route for localhost:port/admin/
and i want to keep the routes.js files and view.js files in matching folders so i wont have too much spaggeti later on
but i keep getting: 500 Error: Failed to lookup view "/admin/manage_subjects"
for trying to create a new route and using same folders few the same
i have the following view folder with express
mainapp(root)
routes(folder)
admin(folder)
index.js(nested inside admin)
index.js(nested inside routes)
views(folder)
admin(folder)
admin_layout.jade(nested inside admin)
manage_subjects.jade(nested inside admin)
index.jade(nested inside views)
layout.jade(nested inside views)
code:
routes/admin/index.js
exports.index = function (req, res) {
res.render('manage_subjects',{title:'Express'});}
views/admin/manage_subjects.jade
extends admin_layout
block content
h1 = title
p Welcome to #{title}
my app.js code
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, admin_routes = require('./routes/admin/')
, user = require('./routes/user')
, http = require('http')
, path = require('path')
, repository = new (require('./domain_model/repository'))();
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
//fill local subjects
repository.subjects.GetAll(function (err, data) {
if (err) throw err;
app.locals.subjects = data;
});
//append routes
app.get('/', routes.index);
app.get('/admin', admin_routes.index);
app.get('/users', user.list);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on http://localhost:' + app.get('port'));
});
I've been dealing with what I think is the same problem and figured out how to fix it. So in case someone else comes across this problem I'm posting my solution.
So here is what I had that was causing 404's and 500's
app.js
var routes = require('./routes/index');
var admin = require('./routes/admin');
app.use('/', routes);
app.use('/admin', admin);
and here was my routes/index.js
//append routes
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.render('index', {title: 'Express'});
});
module.exports = router;
and my routes/admin.js:
var express = require('express');
var router = express.Router();
router.get('/admin', function(req, res) {
res.render('admin/index', {title: 'Express'});
});
module.exports = router;
by defining the second /admin inside the router.get() function I think I was effectively telling node to look for the html in my views folder under the following path views/admin/admin/index.ejs. So to fix that all I had to do was remove either the /admin from the router.get() or the /admin from the app.use()
So my working code now looks like this:
app.js
var routes = require('./routes/index');
var admin = require('./routes/admin');
app.use('/', routes);
app.use('/admin', admin); //I left the /admin here and instead removed the one in routes/admin.js
and here was my routes/index.js
//append routes
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.render('index', {title: 'Express'});
});
module.exports = router;
and my routes/admin.js:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) { //NOTICE THE CHANGE HERE
res.render('admin/index', {title: 'Express'});
});
module.exports = router;
So making that change made it so I could have sub folders in my views folder.
Simple Answer for sub-folders inside the views folder (mine is called frontend)
click here the picture to see the folder structure
file app.js
app.set('views', [path.join(__dirname, 'frontend'), path.join(__dirname, 'frontend/locked'), path.join(__dirname, 'frontend/template'), path.join(__dirname, 'frontend/public')]);
app.set('view engine', 'pug')
I'd check out TJ's video on Modular apps on his vimeo the best part about this work flow is your code becomes really flexible and it's alot easier to stay DRY.
Additionally I would do something like this with my app.set("views")
var path = require("path");
app.set('views', path.join(__dirname, 'views'));
// you can then extend this to the example for routes
Another alternative would be something like in your app.js file:
var express require("express")
var app = express()
var routes = require("./path/to/routes")(app)
and then routes would look like:
routes = function (app) {
app.get("/route", middleWareifYou.gotIt, route.handler || function (req, res) {
res.send("some msg");
});
};
module.exports = routes
Cheers, I hope this helps!
I had a similar problem and what worked for me was setting the views folder in both the main app file and in the router file too.
So in the main app.js file I had:
app.set('views', viewsFolderPath);
And inside my router.js file I also did the same thing:
app.set('views', viewsFolderPath);

Resources