Failed to lookup view "index" in views directory in express - express

Learning express in the meantime I am unable to solve this error which says Failed to lookup view "index" in views directory while my folder structure looks like this
I tried setting the path nothing works
const pathDirectory = path.join(__dirname, '../public')
const viewsPath = path.join(__dirname, '../templates/views')
const partialsPath = path.join(__dirname, '../templates/partials')
app.set('views', path.join(__dirname, viewsPath));
hbs.registerPartials(partialsPath)
app.use(express.static(pathDirectory))
The page of index.hbs should be displayed

Try including
app.set('view engine', 'hbs')
after express.static method.
That would help.

Simply cut your views folder and paste it inside the src.
You can also write
app.set('views', '../templates/views')

instead of:
app.set('views', path.join(__dirname, viewsPath));
try:
app.set('views','viewsPath');

While you run it on the terminal change your directory to webserver, then run the app.js file using
node src/app.js
I tried this and it worked for me.

Related

Difference between app.use(express.static(__dirname + '/public')) and app.use(express.static('public'));

I wonder if the following two are the same.
(1) app.use(express.static(__dirname + "/public"));
(2) app.use(express.static("public"));
Because I think as long as (2) exists in the express server, the browser can serve up the public folder which is located in the root path and __dirname isn't required.
However, sometimes (2) doesn't work while (1) works such as if I render a ejs file in the dynamic route based on Route parameters.
What exactly is the difference between them?
first of all __dirname have 3 usage, you can check documentation:
Making New Directories
To create a new directory in your index.js file, insert __dirname as the first argument to path.join() and the name of the new directory as the second
const fs = require('fs');
const path = require('path');
const dirPath = path.join(__dirname, '/pictures');
fs.mkdirSync(dirPath);
Pointing to Directories
Another unique feature is its ability to point to directories. In your index.js file, declare a variable and pass in the value of __dirname as the first argument in path.join(), and your directory containing static files as the second
express.static(path.join(__dirname, '/public'));
Adding Files to a Directory
You may also add files to an existing directory. In your index.js
file, declare a variable and include __dirname as the first argument
and the file you want to add as the second If you run the express app
from another directory(not root), it’s safer to use the absolute path
of the directory that you want to serve, use __dirname
const fs = require('fs');
const path = require('path');
const filePath = path.join(__dirname, '/pictures');
fs.openSync(filePath, 'hello.jpeg');
based on your example we can don't use __dirname but if you run the express app from another directory, it’s safer to use the absolute path of the directory that you want to serve like this
app.use(express.static(__dirname + "/public"));

How to use folders in views with express app

I have a pug template inside my views folder under views/administration/assets/fixed-assets.pug
My default.pug which the fixed-assets.pug extends from is in my root views folder.
When I try to render the fixed-assets.pug view it looks for the default.pug inside the views/administration/assets/ directory rather than the views directory itself
Everything works fine if I take the fixed-assets.pug and place it in the views directory instead of the views/administration/assets/ directory and update the route accordingly.
How can I tell express to look for the default.pug in the views directory and the fixed-assets.pug in the views/administration/assets/ directory?
Here is my route
var express = require('express');
var secured = require('../lib/middleware/secured');
var router = express.Router();
/* GET fixed-assets page. */
router.get('/administration/fixed-assets', secured(), function(req, res, next) {
res.render('administration/assets/fixed-assets', {
title: 'Fixed Assets'
});
});
module.exports = router;
Here is my views/administration/assets/fixed-assets.pug
extends default.pug
block scripts
if !starter
script(src='/js/main.js')
block view
.animated.fadeIn
h1 Fixed Assets
and this is the error I'm getting
ENOENT: no such file or directory, open
'/usr/src/app/views/administration/assets/default.pug' at
/usr/src/app/views/administration/assets/fixed-assets.pug line 1
Thanks for your help!
In the docs for Includes it says:
If the path is absolute (e.g., include /root.pug), it is resolved by
prepending options.basedir. Otherwise, paths are resolved relative to
the current file being compiled.
The explanation for that is in the API Reference:
basedir: string The root directory of all absolute inclusion.
You can implement basedir globally like this in your main app.js/server.js file:
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.locals.basedir = path.join(__dirname, 'views');

Serving static files from an express/node.js application

Hi I am a newbie and started to learn about node recently. I took an Heroku tutorial on websockets (https://devcenter.heroku.com/articles/node-websockets) and adapted it for a specific project I was working on. In the example code there was a single index.html file with some embedded javascript. I moved this script out to a separate file and referenced it in the HTML. Everything worked fine locally but doesn't work when i deploy to Heroko. I chatted with the very helpful team at Heroku who informed me that my server side code is serving up all files as HTML and I need to change the code. They gave me some pointers and I tried as many things as I could over several days but to no avail. In the end they recommended coming to this forum as a way to solve the problem as it is beyond their scope. The existing code that serves up the index.html file is as follows:
const express = require('express');
const SocketServer = require('ws').Server;
const path = require('path');
const PORT = process.env.PORT || 3000;
const INDEX = path.join(__dirname, 'index.html');
const server = express()
.use((req, res) => res.sendFile(INDEX) )
.listen(PORT, () => console.log(Listening on ${ PORT }));
At first i edited this to include the line:
app.use(express.static('public'))
but this didn't work. I then amended as follows and it still doesn't work:
const INDEX = path.join(__dirname, 'index.html');
const JS = path.join(__dirname, 'client.js');
const server = express()
.use((req, res) => {
res.sendFile(INDEX);
res.sendFile(JS);
I have looked at other tutorials that work when i run them in isolation but when I try to adapt my above code it simply doesn't work. I would really appreciate if someone out there could point me in the right direction.
BTW this is what Heroku told me:
"To explain a bit further this error Uncaught SyntaxError: Unexpected token < is because the URL for http://thawing-journey-33085.herokuapp.com/client.js isn't serving a javascript file but is instead trying to serve the HTML for the homepage. This suggests you have an issue with the routing in your application which you'll need to review. This is probably because your server.js file doesn't check for any particular URL before sending the index.html file."
Thanks
I serve my static files like this:
// define the folder that will be used for static assets
app.use(Express.static(path.join(__dirname, '../public')));
// handle every other route with index.html, which will contain
// a script tag to your application's JavaScript file(s).
app.get('*', function (request, response){
response.sendFile(path.resolve(__dirname, '../public', 'index.html'));
});
This way i set the static folder in the express.static middleware so i can serve the files. And then i redirect all url request to the index.html
To know more: express static

Setting up default view path in Express.js

Source Code
app.js
var express = require('express');
var app = express();
var path = require('path');
var viewPath = path.join(__dirname, 'app/views');
app.set('views', viewPath);
app.set('view engine', 'jade');
app.get('/', function(req, res) {
res.render('index', { title: 'Home Page' } );
});
app.listen(3000);
Folder Structure
app
└───views
│ └───index.jade
└───app.js
Error in Browser
Error: Failed to lookup view index in views directory d:\Users\Admin\Documents\...\project\views
Question
I would like to structure my app by placing the view files in app/views/*.jade, but I cannot get it working so far, using app.set('views', ...) should work but it doesn't
console.log(viewPath) shows d:\Users\Admin\Documents\...\project\app\views
I also tried e.g. app.set('views', 'xxx') but the error still get stucked on the same path, it seems like app.set() has never been called, what's wrong here ?, please guide.
Thanks
Edit
It doesn't matter what I set using app.set('views', 'xxx') the error will always be Error: Failed to lookup view index in views directory d:\Users\Admin\Documents\...\project\views (always keep saying the same path)
I'm so sorry about router.get('/', ...), My actually project's files are different, so I was making mistake here
Try using
app.set('views', path.join(__dirname, 'views'));
Your app.js is in your app folder so I think
var viewPath = path.join(__dirname, 'app/views');
app.set('views', viewPath);
will look into app/app/views/ instead of app/views/ because of __dirname
__dirname is the directory in which the currently executing script resides.
I know it's too late, but might help someone who has the same problem. If you placed the rendering code in a separate file, then you need to use express.Router instead of app.get. For example,
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.render('index', {title: 'Hey', message: 'Hello there!'});
});
module.exports = router;
Then in your app.js,
const router = require('./app/routes/routerName');
app.use('/', router);
I actually have separated files in my project, so I have app.get('/', ...) in the separated route file, then require it to use with app.use()
I really have no ideas but after moving only the app.get('/', ...) to the app.js, the problem has been solved
Thanks everyone
As mentioned by Roxinagi, you should be using app.get().
Everything else seems fine
app.get('/', function(req, res) {
res.render('index', { title: 'Home Page' } );
});
const path = require('path')
app.set('views', path.join(__dirname, 'app/views/'))
app.set('view engine','jade');

How to make an Express site without a template engine?

I do not want Jade or EJS on my site. How can I create an express site without it defaulting to the Jade templates? Thanks
If what you want is directly to serve static html files with the possibility to cache resources, while still being able to hit "/" and get index.html, then the answer is as easy as this:
var express = require('express');
var http = require('http');
var app = express();
app.use(express.static(__dirname + '/public'));
http.createServer(app).listen(3000);
Gotcha: Html files including index.html must be inside /public folder instead of /views
You could use commands below to install express-generator globally and then scaffold a project without a view engine
npm install -g express-generator
express newProject --no-view
You can comment out the lines
app.set 'views', __dirname + '/views'
app.set 'view engine', 'jade'
from the Express initialization code.
If you are serving only static content: https://github.com/visionmedia/express/blob/master/examples/static-files/index.js
Otherwise, use your database, your files, your user input, or whatever to concatenate a string that will make up the http response.
// Express 3.x
app.get('*', function(req,res){
fs.readFile('./foo.txt', 'utf8', function (err, data) {
if (err) throw err;
data += (req.query['something'] || "")
res.type('text/plain');
res.send(200, data);
});
});
With that said: I have grown to love Jade as I've been playing with it for the past few months. It has its idiosyncracies but it's orders of magnitude faster to write any complicated html.
With Express 4.0.0, the only thing you have to do is comment out 2 lines in app.js:
/* app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade'); */ //or whatever the templating engine is.
And then drop your static html into the /public directory. Example: /public/index.html
Use Restify
http://restify.com/
var restify = require('restify'),
fs = require('fs');
var server = restify.createServer({
certificate: fs.readFileSync('path/to/server/certificate'),
key: fs.readFileSync('path/to/server/key'),
name: 'MyApp',
});
server.listen(8080);
It borrows heavily from Express -Routing