Setting up default view path in Express.js - express

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');

Related

Express routes not rendering

I can't figure out why my route 'scrape will not render. I have tried everything I can think of, even changing everything to a very basic route and I just cannot get anything to work.
app.js
const indexRoute = require("./routes/index");
const scrapeRoute = require("./routes/scrape");
// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));
app.use(logger("dev"));
// Routes
app.use("/", indexRoute);
app.use("/scrape", scrapeRoute);
module.exports = app;
here is the route:
const express = require("express");
const router = express.Router();
router.post("/", (req, res) => {
res.send(req.body);
});
module.exports = router;
the index route works just fine. for some reason the route 'scrape' just will not work. I had logic in there to scrape a website but when that wasn't working I figured I'd change it to just a basic route to see if I'm even getting anything and now it's just sending a 404 when I go to localhost:9000/scrape
If you're just going to http://localhost:9000/scrape in the browser, then that is a GET request, not a POST request. And, you would need:
const express = require("express");
const router = express.Router();
router.get("/", (req, res) => {
res.send("hello");
});
module.exports = router;
To get a response from that - change to router.get(). And, because it's a GET request, there is no body so req.body would predictably be empty for a GET request.
To send a POST request from a browser, you either need have the browser submit a form with method="POST" and action="/scrape" as a attributes of the <form> tag or you need to use Ajax to programmatically send a POST request from Javascript using the fetch() interface or the XMLHttpRequest interface.
Are you sure you are making a post call from the client?

How can I link my express server to generated 'dist' directory?

I am getting this error, "TypeError: path must be absolute or specify root to res.sendFile"
root
-dist
|--index.html
|--index_bundle.js
-src
|-server
|-server.js
//server.js
var path = require('path')
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const app = express()
let dataStorage = {};
app.use(cors())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))
app.use(express.static('dist'))
app.listen(8081, function(){
console.log('Server running on port 8081!')
})
app.get('/', function (req, res) {
res.sendFile('../dist/index.html') //need help setting this up
})
app.post('/formHandler', function(req, res){
//post to dataStorage here
})
I am trying to run an express server while also using webpack-dev-server for hot reloading.
I am having trouble with setting up the path to generated 'dist' file.
I am able to just run the webpack-dev-server without express and the file is working then.
Thank you
You can have access to it by serving It's content as express static.
const path = require('path');
app.use(express.static(path.resolve(__dirname, '../../dist'));
You can also define the path at which statics assets can be accessible like this
app.use('/', express.static(path.resolve(__dirname, '../../dist'));
As in your dist folder there are already an index.html file it will be rendered by default when visiting the / path in your browser. No need to specify the index.html file in you request URL

Multiple Errors serving HTML pages with Express

I'm trying to route pages using Express, but I can't seem to route from my main page. I'm using HTML as the view engine and I feel like everything is set up properly, but I'm seeing the error:
"TypeError: path must be absolute or specify root to res.sendFile"
Here is my file structure:
root
-public
--images
--index.html
--main.css
--sponsors.html
--team.html
app.js
I've tried multiple file routes, res.render versus res.sendFile.
var express = require("express")
var app = express()
const port = 3000
var http = require("http")
const path = require('path')
app.set("view engine", "html")
app.listen(port, () => console.log(`Example app listening on port
${port}!`))
app.use(express.static(__dirname + '/public'));
app.get('/sponsors', function(req, res) {
res.sendFile('sponsors')
})
app.get('/', function(req, res) {
res.sendFile('index')
})
app.get('/team', function(req, res) {
res.sendFile('team')
})
To render from a view engine, use res.render(), not res.sendFile().
And, your view engine will need to be able to find a file with that name and an appropriate file extension in the path for the view engine.
If you want to use res.sendFile() without the view engine, then you must specify an actual filename or include the root option that tells it where to look. You must also use the actual file extension on the filename.
Remove the following route method.
// remove the following code
app.get('/', function(req, res) {
res.sendFile('index')
});
Update the default path to the static method you had already written.
app.use('/', express.static(__dirname + '/public'));

express-subdomain won't render views, falls through to main domain

I'm using express-subdomain 1.0.5 with express 4 to route a subdomain for my site. I have localhosts set up and that's working fine. In my main application.js, I have this:
//views
app.engine('ejs', engine);
app.set('views',__dirname + '/views');
app.set('view engine', 'ejs');
//subdomains
var developerRoutes = require('./developerRoutes');
app.use(subdomain('test-developer', developerRoutes));
// main routes
var routes = require('./routes');
app.use(routes);
The developerRoutes file looks like this:
var developer = require('../src/developer');
var devRouter = require('express').Router();
devRouter.get('/', developer.developerHome);
module.exports = devRouter;
and developer looks like this (I expect to have ~10 routes so I'm using a separate file):
exports.developerHome = function(req, res) {
console.log('hi developer got here') //this fires, so I know this route is being called
res.render('developerHome', {
data: {
testData: 'hi'
}
});
}
When I try test-developer.localhost.dev, it 404s (and developerHome.ejs exists). When I try any other route that exists for the main domain but is not present in the developer routes file (e.g. test-developer.localhost.dev/about), it renders the main view. If I try a plain res.send('hi!'); in developer.js, that renders fine.
Is there some ordering of the middleware that I'm missing? I've tried putting the view engine lines both before and after the main and subdomain lines, with no change. Is there any way to make the subdomain routes fall through to the express errorhandling middleware instead of (as it seems) the main routes?
Editing to add -- If I force status and send HTML as below it works, but why?
exports.developerHome = function(req, res) {
console.log('hi developer got here')
res.render('developer/developerHome',
{data:
{
testData: 'hi'
}
},
function(err, html){
if(err) console.log(err);
res.status(200).send(html);
}
);
}

jade extends keyword issues in express.js

Alright, so I am having an issue with express getting my templates to work with the extends/block keywords. I was able to get the index template working just fine; however, when I tried to add a second template, 'extends' does not seem to function. I've pasted the code below, and help would be appreciated! (for reference, I am running express version 2.5.8 and node 0.6.12)
app.js:
var express = require('express')
, routes = require('./routes');
var app = module.exports = express.createServer();
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({ secret: 'your secret here' }));
app.use(app.router);
app.use(express.static(__dirname + '/public'));
app.set('view options', { layout: false, pretty: true });
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
// Routes
app.get('/', routes.index);
app.get('/login', routes.login);
app.listen(3000, function(){
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
});
routes/index.js:
exports.index = function(req, res){
res.render('index', { title: 'rm-dash-r' })
};
exports.login = function (req, res) {
res.render('login', { title: 'rm-dash-r' })
};
In the views/ directory, there are 3 files. index.jade, main-layout.jade, and login.jade. For testing, login and index are identical files.
main-layout.jade:
!!!
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body(style='margin: 0 22%;')
div.container
div.header
a(href='/')
span rm-dash-r
div.stripes
span
div.nav
a(href='/') Blog
a(href='/') About
a(href='/') Projects
div.clearer
span
div.stripes
span
div.main
div.left
div.content
block content
...
index.jade/login.jade:
extends main-layout
block content
h1 testing
Essentially, the route for '/' works without any problems, but the login route will only render the login.jade markup, except with extends main-layout at the top of the page.
If there is any other information that would be helpful to know, please let me know.
alright, after significant trial and error, I seem to have it working. For some reason, after adding a return to the first line of login.jade (ie. extends main-layout is now line 2) it all seems to work.
I haven't the slightest idea why this is the case, but if anybody can shed some light I'd be interested to hear.