Failed to lookup view - node.js

Hi I'm trying to work with Express 3 using handlebars. But I am unable to "lookup the view" I am stuck with this error.
Error: Failed to lookup view "500" in views directory
"d:\projects\meadowlark\site\views" at EventEmitter.app.render
(d:\projects\meadowlark\site\node_modules\express\lib\application.js:519:17)
at ServerResponse.res.render
(d:\projects\meadowlark\site\node_modules\express\lib\response.js:904:7)
at d:\projects\meadowlark\site\meadowlark.js:29:7 at
Layer.handle_error
(d:\projects\meadowlark\site\node_modules\express\lib\router\layer.js:58:5)
at trim_prefix
(d:\projects\meadowlark\site\node_modules\express\lib\router\index.js:269:13)
at
d:\projects\meadowlark\site\node_modules\express\lib\router\index.js:238:9
at Function.proto.process_params
(d:\projects\meadowlark\site\node_modules\express\lib\router\index.js:313:12)
at
d:\projects\meadowlark\site\node_modules\express\lib\router\index.js:229:12
at Function.match_layer
(d:\projects\meadowlark\site\node_modules\express\lib\router\index.js:296:3)
at next
(d:\projects\meadowlark\site\node_modules\express\lib\router\index.js:190:10)
Its really strange for me. Can anyone explain this issue to me how can I solve it?
My js code is as follows:
var express = require('express');
var app = express();
// set up handlebars view engine
var handlebars = require('express3-handlebars')
.create({ defaultLayout:'main' });
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'handlebars');
app.set('port',process.env.port || 3000);
app.get('/', function(req, res) {
res.render('home');
});
app.get('/about', function(req, res) {
res.render('about');
});
// 404 catch-all handler (middleware)
app.use(function(req, res, next){
res.status(404);
res.render('404');
});
// 500 error handler (middleware)
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://localhost: '+ app.get('port') + " Press CTRL+C to terminate.");
});

I think I know what the issue here is, remember this setup of app.js from an O'Reilly book ("Web Development with Node & Express").
Here's what the author fails to clarify:
If you have your .handlebars template files in views/layouts/, structure your view engine setup like this:
var path = require('path');
var express = require('express');
var handlebars = require('express-handlebars'); // 'express3-handlebars' has been deprecated
var app = express();
// Set up handlebars view engine
app.set('views', path.join(__dirname, 'views/layouts/'));
app.engine('handlebars', handlebars({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
Note that you will need the var path = require('path'); in order to set 'views' to the filepath views/layouts/.

If you read the error, it clearly tells you that you are missing a 500 view template in your template directory. I'm not sure what your directory structure you have, but place a 500.handlebars file in the same directory the 404.handlebars file is. Should be somewhere in the views/ or views/layouts directory.

Make sure that your files: home.handlebars, about.handlebars, 404.handlebars, 500.handlebars and main.handlebars don't have hidden extensions. Like this: home.handlebars.html, about.handlebars.html, 404.handlebars.html, 500.handlebars.html, and main.handlebars.html.
If they do, removing those extensions and using only the .handlebars extension should resolve the issue.

Related

Images and css not working with Handlebars

I am working on my portfolio and am using handlebars.
I have my main index.js in my root folder. It is working as far as I can tell. My home(index) page loads locally in my browser, but the css and images for it do not load. I also have my views folder, where my layout.hbs and index.hbs is. Then I also have my images/css folders, where I want my index.hbs to find my images/css (which I pass in as parameters in my res.render in my index.js).
However, when I load my home page, I get the errors:
"[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (style.css, line 0)"
&&
"[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (resize_profile_pic.jpg, line 0)"
Here is my index.js:
// === VARIABLES === //
var express = require('express');
var app = express();
var handlebars = require("express-handlebars");
var path = require("path");
var router = express.Router(); //creates a router object, do I even need this???
//===== view ENGINE SET UP =====//
app.set('view engine', 'handlebars');
app.engine(
"hbs",
handlebars({
layoutsDir: path.join(__dirname, "views/layouts"),
partialsDir: path.join(__dirname, "views/partials"),
extname: ".hbs",
defaultLayout: "layout"
})
);
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "hbs");
//NOT sure what this does??? Or if I need it???
app.use("/public", express.static(path.join(__dirname, "public")));
//saw this on a previous post but doesn't seem to work???
app.use(express.static('images'));
// Route to display static src images - also saw this on a previous post???
app.get("/static", (req, res) => {
res.render("static");
});
//===== .GET PAGES =====//
router.get('/', (req, res, next) => { //also tried app.get, do I need router???
res.render('index', {title: 'Home Page', css:['style.css']});
});
app.use('/', router);
app.listen(3000);
Here is how my image is coded in my index.hbs:
<img src="/images/resize_profile_pic.jpg" alt="">
*I also tried "images/resize_profile_pic.jpg" and nada.

Failed to lookup view using ejs and expressjs

I just start learning NodeJS and seems amazing to me. Anyway, I'm facing a weird issue about the view rendering. Essentially I want use the MVC pattern, so I organized my project in the following way:
Inside app.js I wrote the following code:
const express = require('express');
const app = express();
require('./config/environment.js')(app, express);
require('./config/routes.js')(app);
app.listen(process.env.PORT || 3000);
Essentially, I declared the server using expressjs 'cause is indicated for MVC application, and then I placed all the configuration for the environment within envinroment.js, passing to the constructor of the module the app and the express:
module.exports = function(app, express){
app.set('development', function(){
app.use(express.errorHandler({
dumpExceptions: true,
showStack: true
}));
});
app.set('production', function(){
app.use(express.errorHandler());
});
app.set('view engine', 'ejs');
app.set('views', __dirname);
if(process.env.NODE_ENV === 'production'){
app.set('port', 80);
}
};
as you can see I setted as view engine the ejs package, so in this way I can render html file within a javascript file and pass information to the view.
Then in routes.js I wrote:
module.exports = function(app){
app.get('/', function(req, res){
res.render('home.ejs', {counter: 2});
});
};
this is the code that cause the problem, infact when I load my application I get:
Failed to lookup view "home.ejs"
I also tried using:
const path = require('path');
res.render(path.join(__dirname+'/views/home.ejs'), {counter: 2});
but same problem..
Thanks in advance for any help
Add
let path = require('path');
to the start of your script.
Then, in your app.js write:
app.set("views", path.join(__dirname, "..", "views"));
instead of just "app.set('views', __dirname);".
And in your routes.js write:
res.render('home', {
counter: 2
});

Node.js / Express app not returning the correct EJS page

I am building a website using Node.js, Express and EJS. For now I have two EJS templates, each corresponding to a page on the website:
the home page URL should be / or /home. The "staff" URL should be /staff. The home one works fine, but for some reason even when I visit the /staff or even a nonsense address (e.g., /eduwshduhwudhwud) I still get the home page. Here is my code that's inside the app.js which is used to build the routes.
Here is my folder structure and code:
var express = require("express");
var app = express();
app.use(express.static("public")); // To allow static files
app.set("view engine", "ejs");
// -------------------------------- HOME PAGE-----------------------------------
app.get("/", function(req, res){
res.render("home");
});
app.get("/home", function(req, res){
res.render("home");
})
// -------------------------------- STAFF PAGE-----------------------------------
app.get("/staff", function(req, res){
res.render("staff");
});
// -------------------------------- HOME PAGE-----------------------------------
// -------------------------------- HOME PAGE-----------------------------------
// -------------------------------- HOME PAGE-----------------------------------
app.listen(process.env.PORT, process.env.IP, function(){
console.log("SERVER IS RUNNING!");
})
Use path.join(__dirname, 'views') to combine the application's directory (i.e., _dirname) to your views directory.
This is how I am doing it in my application:
var express = require('express');
var path = require('path');
...
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views')); // <-- add this line before your view engine definition
app.set('view engine', 'ejs');
...
Given this, within my routes I can refer to any view in the views folder with res.render(). For example:
res.render('dashboard', { title: 'My App', greeting: 'Hello' });

Node.js Express not rendering html view

so I was trying to follow a tutorial to use node.js as the front end of a wordpress site
This one http://www.1001.io/improve-wordpress-with-nodejs/
Here is the code from server.js
var frnt = require('frnt');
var fs = require("fs");
var path = require("path");
var express = require('express');
var app = express();
var doT = require('express-dot');
// Define where the public files are, in this example ./public
app.use(express.static(path.join(__dirname, 'public')));
// Make sure this is set before the frnt middleware, otherwise you won't
// be able to create custom routes.
app.use(app.router);
// Setup the frnt middleware with the link to the internal server
app.use(frnt.init({
proxyUrl: "http://localhost:8888/frnt-example/wordpress", // The link to your wordpress site
layout: false // We simplify this example by not using layouts
}));
// define rendering engine
app.set('views', path.join(__dirname, "views"));
app.set('view engine', 'html' );
app.engine('html', doT.__express );
// respond with "Hello World!" on the homepage
app.get('/', function (req, res) {
res.send('./views/index.html');
});
app.listen(8080); // listen to port 8080
It keeps outputting the following
./views/index.html
Rather than rendering the html?
I've never used frnt, but res.send sends a string so that's no big surprise.
Look at res.sendfile which sends the contents of a file.
I prefer to use ejs , it's sems like html just edit index.html to index.ejs
1- install ejs module npm install ejs
2- add this in app.js
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
and render the index.ejs by using
app.get('/', function (req, res) {
res.render('index'); // or res.render('index.ejs');
});
res.send() // it send just a string not file
Hope it usefull !

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