I am new to nodejs and I am getting the following error.
Error: Failed to lookup view "home" in views directory "/views"
I am running the app via a service file. The service file starts the app but I get the above error. However when I start the app using nodejs app.js I do not get the failed error and the app works normally.
app.js file
var express = require('express');
var app = express();
var routes = require('./routes');
var path = require('path');
app.use(express.static(path.join(__dirname, 'public')));
app.set('view engine','ejs');
app.get('/starwars/',routes.home);
routes file.
var moviesJSON = require('../movies.json');
exports.home = function(req,res){
var movies = moviesJSON.movies;
res.render('home',
{
title:'Star Wars Movies.',
movies: movies,
//movies:['Episode 1','Episode 2','Episode 3']
}
);
};
I've tried changing the routes location to ../routes but that is giving me a bad gateway error. So I am stumped.
service file
User=webuser
Group=webgroup
ExecStart=/usr/bin/nodejs /home/pi/examples/nodeapp/star_wars_movie_app/app.js
I needed to add the following line to app.js
app.set('views', path.join(__dirname, 'views'));
Related
I'm working through a PluralSight course/project on NodeJs and Express. They have a project template with tests. The app is working, it is actually finding and rendering the view. But the test for setting the views directory is failing. I have tried many variations of directories for the views, with and without the '/' after the '/views'; I have tried many variations of using the path.join(__dirname, './src/views') as well. Nothing seems to satisfy the test, even when I tried using the same values in the test, as in app.set('views', path.join(__dirname, '../../src/views')) Nothing seems to satisfy the test.
The tests are run with npm run test:module1. When that runs there is a line in the console: mocha --exit './test/module1/*.spec.js' The test is definitely finding the app because it runs 8 tests; 7 pass and only this one fails.
But I'm trying to re-learn modern JS, as well as Express and ejs, so I may be missing something basic.
Here's my app.js code:
const fs = require('fs');
const path = require('path');
const express = require('express');
const app = express();
app.set('views', './src/views');
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, '/public/')))
app.get('/', function(req, res) {
res.render('index', { title: 'Index'});
})
app.listen(3000, function() {
console.log('PS Project Running on port 3000!');
});
and here's their relevant test:
const path = require('path');
describe('View engine and directory', () => {
it('should set view engine and directory #app-set-views-directory-engine', () => {
assert(typeof app === 'function', '`app` const has not been created in `app.js`.');
assert(app.settings['view engine'] === 'ejs', 'The view engine has not been set to `ejs`.');
assert(app.settings.views === path.join(__dirname, '../../src/views'), 'The view directory has not been set to the `views` directory.');
});
});
I'm working in Cloud9 and when trying to run the application i'm greeted with the error failed to lookup view "/landing.ejs" in views directory:
Thus far I have:
var express = require("express");
var app = express();
app.get("/", function(req, res){
res.render("/landing.ejs");
})
app.listen(process.env.PORT, process.env.IP, function(){
console.log("Server is running");
})
My file tree is structed as such App > v1 > app.js package.json views > landing.ejs
At first,you have to set default view files path app.set('views', __dirname + '/view_files_folder_path'); after the line var app = express(); .
Then modify this res.render("/landing.ejs"); to res.render("landing.ejs");
Hope this will work :)
Say for example in my node_module folder I have an npm called project which has some set defined express routes. For example,
var express = require('express');
var router = express.Router();
router.get('/', function (req, res, next) {
res.render('indexPage', {title: 'Homepage'});
});
module.exports = router;
which is kept in a routes.js file
How would this be accessed in the main node project file index.js file?
I have attempted to use require() function, however, this doesn't work.
After you set your app as an Express app then add your routes middleware(s) like the below.
Also I've added some useful code parts (a simple Express app) for any beginner:
// defining an express app
var express = require('express')
var app = express()
var server = require('http').Server(app)
// setting the express app - in case of needed
app.set('x-powered-by', false) // hide x-powered-by header!
app.set('view engine', 'ejs'); // set EJS as view engine!
app.set('views', __dirname + '/views'); // specifying the directory that contains view files
// THIS IS YOUR ANSWER PART
app.use(require('./routes'))
...
...
// Other middlewares
app.use(require('./middlewares/someMiddleware'))
// Catching 404 errors
app.use('*', function(req,res){
res.status(404).send("URL not found.")
})
// Catching and evaluating the other errors
app.use(require("./middlewares/errorHandler"))
server.listen(3001, function() {
console.log('APP Server is listening HTTP port 3001')
})
Generally the last route is been 404 error. So, if the request has not been caught in any route before 404, that means "the page cannot found".
Also, errorHandler middleware takes 4 arguments (error, request, response and next).
So, if you encountered with an error in your routes.js, and if you send this error in routes files by using next(err) this error can be caught on errorHandler middleware.
This is basic information which everyone needs when starting to develope an Express application.
For more details:
http://expressjs.com/en/guide/using-middleware.html
Good luck...
I'm having some trouble with routing and serving static files.
My directory structure is like this:
app/
--app.js
—-public/
—-js/
—-main.js
—-views/
—-pages/
—-index.jade
This is how I've set up my server:
app.js
var express = require('express')
var path = require('path')
var serveStatic = require('serve-static')
var publicPath = path.join(__dirname,'..','public');
var port = process.env.PORT || 3000
var app = express()
app.set('views', './views/pages')
app.set('view engine', 'jade')
app.use('/public', serveStatic(publicPath));
app.listen(port)
console.log("port is " + port)
app.get('/', function(req, res) {
res.render('index', {
title: 'index',
})
})
index.jade
doctype
html
head
meta(charset="utf-8")
title index
script(src="/public/js/main.js”)
body
h1=title
But this is what happens when I visit the index:
GET http://localhost:3000/public/js/main.js 404 (Not Found)
How do I set up the "serve-static" part to work?
Thanks!
you are passing the wrong parameter to it.
correct example for serving static files from different directory would be
This example shows a simple way to search through multiple directories. Files are look for in public-optimized/ first, then public/ second as a fallback.
var express = require('express')
var serveStatic = require('serve-static')
var app = express()
app.use(serveStatic(__dirname + '/public-optimized'))
app.use(serveStatic(__dirname + '/public'))
app.listen(3000)
check out the docs for more options https://github.com/expressjs/serve-static
I think you need to remove public from the path.
script(src="/js/main.js”)
You're telling the server static resources are served from the public folder.
I decided to adopt a vertical structure for my Node.js+Express project, as a consequence I have sub-projects/sub-folders (User management, Cart, Inventory) by feature:
Project
--core
----views
----(...)
--usermgmt
----views
and obviously controllers, routes, models and views are defined for every feature.
My problem now is how to set the views directory for the project. I mean when I do that in horizontal structure, I write:
app.set('views', path.join(__dirname, 'views'));
It is easy since the views directory is unique
but now, I have many views directories so I don't know what the best practice is. For the moment, I set the variable views to __dirname and when I render I go from the root directory to the corresponding one.
Any advice?
I'd quote from the documentation itself.
A directory or an array of directories for the application's views. If
an array, the views are looked up in the order they occur in the
array.
http://expressjs.com/en/4x/api.html#app.set
(Scroll down and find views in table just below)
OR
You can create each of your feature as separate app (just don't do app.listen) then in your master app you can do something like this
Launch.js
#!/usr/bin/env node
var http = require('http');
var app = require('express')();
app.use('/feature1',require('./feature1');
app.use('/feature2',require('./feature2');
// Setup port
var port = process.env.PORT || 3000;
app.set('port', port);
//Create HTTP server.
var server = http.createServer(app);
//Listen on provided port, on all network interfaces.
server.listen(port);
server.on('listening', function(){
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
//You can open browser -- uncomment below line
//require("openurl").open("http://localhost:3000");
debug('Magic happens at : http://localhost:' + addr.port);
});
Your feature directories would contain an index.js which would do ...
.js
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var settings = require('./lib/settings');
//Import your routes
var defRoute = require('./defRoute');
var users = require('./users');
var someOtherResource = require('./someOtherResource');
var app = express();
// view engine setup
//This sets view for `this` app to relative `views` folder
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
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')));
//Mount your routes
app.use('/',defRoute);
app.use('/users', users);
app.use('/someOtherResource', someOtherResource')
//Other awesome code
//Return this app.
module.exports = app;
Hope this helps!
Thanks! So, it works well with using a directory of views. I will try the second option while I will do a major refactoring
mph