I'm trying to make a better experience of nodeJS and i don't really like to get all the script in one file.
so, i used this structure
./
public/
css/
styles.css
images
views
index.ejs
profile.ejs
app.js
routes.js
My files right now:
app.js
var express = require('express');
var app = express();
app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');
app.use(express.static(__dirname + '/public'));
// routes
require('./routes.js')(app);
app.listen(1337);
In routes.js, if I use res.render('index') then its working while when I use res.render('profile') then it is giving error Failed to lookup view "profile" in views directory
routes.js ----- Working
module.exports = function(app) {
app.get('/', function(req, res) {
res.render('index');
});
};
routes.js ----- Not Working
module.exports = function(app) {
app.get('/', function(req, res) {
res.render('profile');
});
};
Assume that index.ejs and profile.ejs have same content.
Can anyone explain what is the problem if I use res.render('profile') in routes.js
Edit: Complete Error message:
Error: Failed to lookup view "profile" in views directory "/home/anand03/Desktop/mynode/views"
at EventEmitter.render (/home/anand03/Desktop/mynode/node_modules/express/lib/application.js:579:17)
at ServerResponse.render (/home/anand03/Desktop/mynode/node_modules/express/lib/response.js:960:7)
at /home/anand03/Desktop/mynode/routes2.js:10:12
at Layer.handle [as handle_request] (/home/anand03/Desktop/mynode/node_modules/express/lib/router/layer.js:95:5)
at next (/home/anand03/Desktop/mynode/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/home/anand03/Desktop/mynode/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/anand03/Desktop/mynode/node_modules/express/lib/router/layer.js:95:5)
at /home/anand03/Desktop/mynode/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/home/anand03/Desktop/mynode/node_modules/express/lib/router/index.js:330:12)
at next (/home/anand03/Desktop/mynode/node_modules/express/lib/router/index.js:271:10)
Related
My app can not find a page from the views directory. I think I've setup the configuration correctly and other files are working fine in views but this one is not working.
Error: Failed to lookup view "users/register" in views directory "D:\NODE PROJECTS\MyBlog\views"
at Function.render (D:\NODE PROJECTS\MyBlog\node_modules\express\lib\application.js:580:17)
at ServerResponse.render (D:\NODE PROJECTS\MyBlog\node_modules\express\lib\response.js:1017:7)
at file:///D:/NODE%20PROJECTS/MyBlog/src/routes/UserRouter.js:18:9
at Layer.handle [as handle_request] (D:\NODE PROJECTS\MyBlog\node_modules\express\lib\router\layer.js:95:5)
at next (D:\NODE PROJECTS\MyBlog\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (D:\NODE PROJECTS\MyBlog\node_modules\express\lib\router\route.js:112:3)
This is my path setup
app.engine('ejs', engine)
app.set('view engine', 'ejs')
app.set('views', path.join(__dirname, '../templates/views'))
And a call from router
UserRoter.get('/register', (req, res)=>{
res.render('users/register', {title: 'Sign Up'})
})
And this is the structure of views directory
You have a bug in the third line of code, instead of:
app.set('views', path.join(__dirname, '../templates/views'))
Should be:
app.set('views', path.join(__dirname, '/templates/views'))
I mirrored your project (folder and file structure) and everything seems to be fine:-)
Folder & file structure :
app.js
const express = require("express");
const path = require("path");
const port = 3000;
const app = express();
app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "/templates/views"));
app.get("/", (req, res) => {
res.render("index", { title: "Keep Calm and Do not stop coding!" });
});
app.get("/register", (req, res) => {
res.render("users/register", { title: "Sign Up" });
});
app.listen(port, () => {
console.log(`Server is listening at http://localhost:${port}`);
});
register.ejs
<title><%= title %></title>
<h1>Register page works fine!</h1>
output:
Tested with "ejs": "^3.1.6", "express": "^4.17.2", node 16.13.0
view-engine
I have installed hbs instead of handlebar for dynamic templating, and now I'm stuck at this problem.
Error: Failed to lookup view "index" in views directory "/home/trijay/Desktop/NodeJs/web-server/src/views"
at Function.render (/home/trijay/Desktop/NodeJs/web-server/node_modules/express/lib/application.js:580:17)
at ServerResponse.render (/home/trijay/Desktop/NodeJs/web-server/node_modules/express/lib/response.js:1008:7)
at app.get (/home/trijay/Desktop/NodeJs/web-server/src/app.js:14:9)
at Layer.handle [as handle_request] (/home/trijay/Desktop/NodeJs/web-server/node_modules/express/lib/router/layer.js:95:5)
at next (/home/trijay/Desktop/NodeJs/web-server/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/trijay/Desktop/NodeJs/web-server/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/trijay/Desktop/NodeJs/web-server/node_modules/express/lib/router/layer.js:95:5)
at /home/trijay/Desktop/NodeJs/web-server/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/home/trijay/Desktop/NodeJs/web-server/node_modules/express/lib/router/index.js:335:12)
at next (/home/trijay/Desktop/NodeJs/web-server/node_modules/express/lib/router/index.js:275:10)
Below is my code for app.js and also I have installed the hbs, express library. Any help will be appreciated
//app.js
const express = require('express')
const path = require('path')
const publicPath = path.join(__dirname, '../public') //for accessing comeplete file
const app = express() //express being initialised
app.use(express.static(publicPath))
app.set('view engine', 'hbs') //use to set handle bars. we need to provide key value pair
app.get('', (req, res) => {
res.render('index') //need to provide the hbs file name which you will find in view
})
app.get('/weather', (req, res) => {
res.send({
latitude: -57.89,
longitude: 78.42,
location : 'New Delhi'
})
})
app.listen(3000, () => {
console.log('Server Started on port 3000')
})
Add a views directory to the engines options:
app.set('view engine', 'hbs')
app.set('views', path.join(__dirname, '../views'));
As you can see in the error message:
Error: Failed to lookup view "index" in views directory "/home/trijay/Desktop/NodeJs/web-server/src/views"
res.render('index') points somewhere in src directory.
I think you may forgot to setup the engine after defining it.
app.set('view engine', 'hbs');
app.engine( 'hbs', hbs( {
extname: 'hbs',
defaultView: 'index' //your default template
}));
Try this and let me know.
My app only works on port 3000.
If i change port to anything else, it'll work but when a page loads it occurs this error.
abc is not defined
at eval (eval at compile (C:\Users\ASUS\node_modules\ejs\lib\ejs.js:549:12), :22:26)
at returnedFn (C:\Users\ASUS\node_modules\ejs\lib\ejs.js:580:17)
at tryHandleCache (C:\Users\ASUS\node_modules\ejs\lib\ejs.js:223:34)
at View.exports.renderFile [as engine] (C:\Users\ASUS\node_modules\ejs\lib\ejs.js:437:10)
at View.render (C:\Users\ASUS\node_modules\express\lib\view.js:128:8)
at tryRender (C:\Users\ASUS\node_modules\express\lib\application.js:640:10)
at EventEmitter.render (C:\Users\ASUS\node_modules\express\lib\application.js:592:3)
at ServerResponse.render (C:\Users\ASUS\node_modules\express\lib\response.js:971:7)
at C:\Users\ASUS\Desktop\nodeweb\controllers\index.js:21:6
at Layer.handle [as handle_request] (C:\Users\ASUS\node_modules\express\lib\router\layer.js:95:5)
abc is a variable i'm using in index.ejs, defined in router.
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.render('index', {abc: 23})
});
module.exports = router;
I'm starting my server with node app command
var app = express();
app.set('view engine', 'ejs')
app.use(express.static(__dirname + '/public'));
app.use(require('./controllers'))
app.listen(8080, function() {
console.log('Listening on port 8080...')
})
UPDATE
I think i found the problem
It works when i use
app.use('/', function(req, res) {
res.render('index', {tit:[1,2,3,4,5]});
})
instead of
app.use(require('./controllers'))
But why?
UPDATE
It just fixed itself, it works normally now and i don't know why. That sucks.
You could try hard coding the port:
app.set("port", process.env.PORT || 3000);
Or this:
$ PORT=8080 node app.js
Also if you are not on Windows, and want to use ports bellow 1024 try this first:
sudo PORT=80 node app.js
If you want to place the route handlers in a separate file, then you can, just no need to call the file with app.use(...).
Instead, you can just do:
require('./controllers');
It has nothing to do with the abc variable.
It is because , I think controller is not properly imported . If you write like this I think, it will work fine
var router = require('express').Router();
router.get('/', function(req, res) {
res.render('index', {abc: 23})
});
module.exports = router;
var app = express();
var route = require('./router')
app.set('view engine', 'ejs')
app.use(express.static(__dirname + '/public'));
app.use('/',route);
app.listen(8080, function() {
console.log('Listening on port 8080...')
})
Here be careful when you define require('./router') in var route = require('./router') ,because it is relative so it totally depends on your folder structure.
I have a problem to route views by node.js and express.js
The tree of my project is look like :
app/
app.js
views/
index.html
login.html
public/
css/
js/
I use express and path ; Here is my code to set paths:
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
//forms
app.set('views', path.join(__dirname, 'views'));
//public
app.use(express.static(path.join(__dirname, 'public')));
And I am getting this error:
Error: Failed to lookup view "login.html" in views directory "/home/Project/V0.0.8_3/app/views"
at EventEmitter.render (/home/Project/V0.0.8_3/node_modules/express/lib/application.js:580:17)
at ServerResponse.render (/home/Project/V0.0.8_3/node_modules/express/lib/response.js:966:7)
at /home/Project/V0.0.8_3/app/routes/login.js:11:11
at Layer.handle [as handle_request] (/home/Project/V0.0.8_3/node_modules/express/lib/router/layer.js:95:5)
at next (/home/Project/V0.0.8_3/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/Project/V0.0.8_3/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/Project/V0.0.8_3/node_modules/express/lib/router/layer.js:95:5)
at /home/xvps/Tracker/V0.0.8_3/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/home/Project/V0.0.8_3/node_modules/express/lib/router/index.js:335:12)
at next (/home/Project/V0.0.8_3/node_modules/express/lib/router/index.js:275:10)
at Function.handle (/home/Project/V0.0.8_3/node_modules/express/lib/router/index.js:174:3)
at router (/home/Project/V0.0.8_3/node_modules/express/lib/router/index.js:47:12)
at Layer.handle [as handle_request] (/home/Project/V0.0.8_3/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/Project/V0.0.8_3/node_modules/express/lib/router/index.js:317:13)
at /home/Project/V0.0.8_3/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/home/Project/V0.0.8_3/node_modules/express/lib/router/index.js:335:12)
and when I try to get a file from public directory I get this error:
Cannot GET /js/login.js
Actually I know different between local path and server path and I have read a lot of related questions have been asked in stack overflow but I cannot find what is my mistake.
UPDATE
And the routing code is here:
var router = express.Router();
require('./router')(app);
the router.js:
var routes = require('./routes/index');
var login = require('./routes/login');
module.exports = function (app) {
/* Index(main) route */
app.use('/', routes);
app.use('/index', routes);
app.use('/index.html', routes);
app.use('/login', login);
app.use('/login.html', login);
app.use('/logout', logout);
};
at routes directory there are two js files; index.js and login.js
index.js:
var express = require('express');
var router = express.Router();
router.route('/')
// fetch all users
.get(function (req, res) {
console.log('get method');
if(req.session.logged) {
res.render('index.html');
}
else {
res.redirect('/login');
}
});
module.exports = router;
Which express version are you using?
Updated
In express 4 middlewares are built in external modules, so for static files in you case, you should use serve-static middleware:
Example code:
var express = require('express')
var path = require('path')
var serveStatic = require('serve-static')
var app = express()
app.use(serveStatic(path.join(__dirname, 'public')))
app.listen(3000)
Because I was beginner on coding by node.js and uploading on server I was running my code on server by npm, one of my friends helped me t find my problem. I must run the app by pm2 to get a live application.
I was also getting this error, but after getting some mental fatigue I am able to resolve this. Here is the solution that works fine for me.
Change this line of code app.set('views', path.join(__dirname, 'views')); to app.set('views', path.join(__dirname, '../views')); this.
Looks like a simple task, but I can not find out the error in my code.
app.js
var http = require('http');
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var routes = require('./routes')(app);
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.set('view engine', 'jade');
app.set('views', './views');
app.use(express.static('./public'));
app.listen(3000, function() {
console.log('hello');
console.log('express server listening on port:' + 3000);
});
index.jade
html
head
title Welcome
body
p Enter your name and email address to become a member.
form(action='/signup', method='post')
div
label Name
input(type='text', name='name')
div
label Email
input(type='text', name='email')
div
input(type='submit')
routes.js
module.exports = function(app) {
app.get('/', function(req, res) {
res.render('index');
});
app.post('/signup', function(req, res) {
console.log(req);
console.log(req.body);
var name = req.body.name;
var email = req.body.email;
console.log('Name: ' + name);
console.log('Email: ' + email);
res.json(req.body);
});
};
When I post the form I get the error:
TypeError: Cannot read property 'name' of undefined
at /Users/demas/temporary/express/1/routes.js:11:22
at Layer.handle [as handle_request] (/Users/demas/temporary/express/1/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/demas/temporary/express/1/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/Users/demas/temporary/express/1/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/demas/temporary/express/1/node_modules/express/lib/router/layer.js:95:5)
at /Users/demas/temporary/express/1/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/Users/demas/temporary/express/1/node_modules/express/lib/router/index.js:330:12)
at next (/Users/demas/temporary/express/1/node_modules/express/lib/router/index.js:271:10)
at expressInit (/Users/demas/temporary/express/1/node_modules/express/lib/middleware/init.js:33:5)
at Layer.handle [as handle_request] (/Users/demas/temporary/express/1/node_modules/express/lib/router/layer.js:95:5)
In the console I can see the req.body is undefined. Why?
You need to do your configuration before you do the routing, so moving down this line :
var routes = require('./routes')(app);
Below this :
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
... should work.