I have the following folder structure:
bin
controllers
models
node_modules
public
routes
views
app.js
package.json
As I am new to node.js and express.js, I would like to know how to render .ejs file from the controller file. Currently, my code looks like:
//controllers/login.js
module.exports = {
getLoginPage: function (req, res) {
res.render('login-form');
}
};
//routes/login.js
var login = require('../controllers/login');
module.exports = function(app){
app.get('/', login.getLoginPage);
};
//app.js
var express = require('express');
var http = require('http');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser'); //parses information from POST
var stylus = require('stylus');
var validator = require('express-validator');
var session = require('express-session');
var app = express();
require('./routes/login')(app);
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(validator());
app.use(cookieParser());
app.use(stylus.middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({secret: 'max', saveUninitialized: false, resave: false}));
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
In my controller, if I write res.send("Hello");, it prints but I want the entire .ejs file to show up on my browser. How is this possible?
Also, if I render the .ejs from my routes, it's displaying properly but not from the controllers.
//error
Error: Failed to lookup view "error" in views directory "C:\node\folder-name\views"
at EventEmitter.render (C:\node\folder-name\node_modules\express\lib\application.js:580:17)
at ServerResponse.render (C:\node\folder-name\node_modules\express\lib\response.js:971:7)
at C:\node\folder-name\app.js:60:7
at Layer.handle_error (C:\node\folder-name\node_modules\express\lib\router\layer.js:71:5)
at trim_prefix (C:\node\folder-name\node_modules\express\lib\router\index.js:315:13)
at C:\node\folder-name\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\node\folder-name\node_modules\express\lib\router\index.js:335:12)
at next (C:\node\folder-name\node_modules\express\lib\router\index.js:275:10)
at Layer.handle_error (C:\node\folder-name\node_modules\express\lib\router\layer.js:67:12)
at trim_prefix (C:\node\folder-name\node_modules\express\lib\router\index.js:315:13)
Thanks
Change your view path to this:-
app.set('views',path.join(__dirname+'/views/'));
then in controller you can simply use
//assuming hello.ejs is in your view folder
response.render('hello.ejs');
and if you have folders in views folder then use
response.render('error/404.ejs');
First, you need to set the rendering engine for views:
app.set('view engine','ejs');
You need to set the view engine to ejs :
app.set('view engine', 'ejs')
Docs
Try the following:
var path = require('path');
res.render(path.resolve('./views/error'))
Related
I am facing some errors while integrating hbs and express in node js
content from layouts& partials are getting not loaded ,even though they are connected to
app.js , layout is loading when we move it into root of view.its not loading when its in a folder inside view.
When i move layouts.hbs to root it starts to load but partials are not loading since its inside a folder.(error:The partial my_partial could not be found)
when i googled about partial i found that hbs.registerPartial(path.join(__dirname, "/views/partials")); could be used but it showed an error that hbs.registerPartial is not a function.
so anyone please suggest me what to do
I expect solution for
How can i load default layout and partials by creating folders named layouts and partials respectively
-- views
-- partials
partial1.hbs
partial2.hbs
-- layouts
layout.hbs
app.js
error.hbs
//app.js
var createError = require('http-errors');
var express = require('express');
const hbs = require('express-handlebars');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
hbs.registerPartial(path.join(__dirname, "/views/partials"));
app.engine("hps", hbs.engine({ extname: "hbs", defaultLayout: "layout", layoutsDir: path.join(__dirname, 'views', "layout"), partialsDir: path.join(__dirname, 'views', "partials") }))
console.log(path.join(__dirname, 'views', "layout"))
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
I'm trying to access my routes /api and /api/superheroes, but i'm getting this error when I do that.
Not Found
404
NotFoundError: Not Found
at C:\Users\mikae\Desktop\Project\node-express-swig-mongo\app.js:27:8
at Layer.handle [as handle_request] (C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:317:13)
at C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:275:10)
at C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:635:15
at next (C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:260:14)
at Function.handle (C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\mikae\Desktop\Project\node-express-swig-mongo\node_modules\express\lib\router\index.js:47:12)
app.js
var api = require('./routes/api.js');
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/api', api);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
api.js
var express = require('express');
var router = express.Router();
router.get('/superheros', function(req, res) {
res.send('Just a test');
});
module.exports = router;
I'm following a tutorial and I already saw from scratch again and I didn't found the solution. I just want to access the routes that I've created to continue the lesson. Someone can help me? What should I do?
You've got a typo: it says /superheros (heros, not heroes) in api.js. Also, under /api, you're mounting a Router instance that has exactly one route defined: /superheros. There's no / route in the Router that you pass to:
app.use('/api', api);
And so, there is no handler for /api + /.
I am a newbie to use express and as a result am bungling my way through making this web app.
I have my routes in a different file called route.js inside a module.export, and I manage all this inside app.js and I want to be able to serve a HTML page and keep it in the module. I've done so using sendFile but it doesn't serve the CSS and JS as well. What can I do to fix this?
app.js
//setup
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var users = require('./routes/users');
var app = express();
var port = process.env.PORT || 3000;
var mongoose = require('mongoose');
var flash = require('connect-flash');
var passport = require('passport');
var session = require('express-session');
var path = require('path');
//db
var configDB = require('./config/database.js');
mongoose.connect(configDB.url);
require('./config/passport')(passport);
// view engine setup
//app.set('views', path.join(__dirname, 'views'));
//app.set('view engine', 'jade');
app.set('view engine', 'ejs');
//routes
//app.use('/', index);
//app.use('/users', users);
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
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')));
//passport
app.use(session({secret: 'secret'}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
//routes
require('./app/routes.js')(app, passport);
// catch 404 and forward to error handler
/*app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});*/
// error handler
/*app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});*/
module.exports = app;
//launch
app.listen(port);
console.log('Website starting on port ' + port);
routes.js
module.exports = function(app,passport) {
...
//--timesheet section---
app.get('/timesheet', function(req, res) {
var path = require('path');
res.sendFile(path.resolve('public/timesheet.html'));
});
...
}
You want to use a view engine and a static directory. You have some of the code already.
Your view engine using .ejs:
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
And you can define your static and specify a path prefix:
app.use('/assets', express.static(path.join(__dirname, 'public')));
In your views directory, put your htmls with .ejs extension, such as timesheet.ejs. You can then create an assets directory for your css/js/image files and reference them in your timesheet.ejs using /assets/style.css.
Finally, in your route, you'll want to render the template:
res.render('timesheet')
My express application seems to return 404 NOT FOUND whenever im using a post request method in my routes file. GET-requests are working fine and i can only see "GET" requests in the console aswell, even if im using a post request.
Is there some missing link between app.js and routes/index.js that might be causing this?
// routes/index.js
router.post('/foo', function (req, res, next) {
res.setHeader('Content-Type', 'application/json');
res.send('You sent: sdadad to Express');
})
// App.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var app = express();
var cors = require('cors')
app.use(cors())
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
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')));
app.use('/', index);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Result:
Not Found 404
Error: Not Found
at C:\Users\willow\Desktop\backend\app.js:29:13
at Layer.handle [as handle_request] (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:317:13)
at C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:275:10)
at C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:635:15
at next (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:260:14)
at Function.handle (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:174:3)
at router (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:47:12)
at Layer.handle [as handle_request] (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\layer.js:95:5)
at trim_prefix (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:317:13)
at C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:284:7
at Function.process_params (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\willow\Desktop\backend\node_modules\express\lib\router\index.js:275:10)
at SendStream.error (C:\Users\willow\Desktop\backend\node_modules\serve-static\index.js:121:7)
What you wanna do should look like this in practice:
// routes/index.js
module.exports = (express) => {
// Create express Router
var router = express.Router();
// add routes
router.route('/foo')
.post((req, res) => {
res.setHeader('Content-Type', 'application/json');
res.send('You sent: sdadad to Express');
});
return router;
}
// App.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes')(express); // require routes at routes/index.js
var app = express();
var cors = require('cors')
app.use(cors())
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
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')));
app.use('/', routes);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
What I usually do is create a function that expects express as param like this
(routes/index.js)
module.exports = (express) => {
// Create express Router
var api = express.Router();
// add routes
api.route('/some_endpoint')
.post((req, res) => {
res.json({ message : 'some message' })
});
return api;
}
then I just import this file to my app.js
like this
(app.js)
// set api as a middleware
const api = require('./routes')(express);
app.use('/api/v1', api);
that way I hook up my api and my server.
I've created a build environment using express JS. But, I got into trouble to configure AngularJS view -- Pleas help me to fix this issue..
1:
var express = require('express');
var http = require('http');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
var httpServer = http.createServer(app);
// view engine setup
//app.set('views', path.join(__dirname, 'views'));
//app.set('view engine', 'jade');
//res.render('dist/index.html');
//app.engine('html', require('ejs').renderFile);
//Trying to setup my view over here -- dist folder is holding the index.html file
app.set('views', __dirname + '/dist');
app.set('view engine', 'html');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/dist/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static('./dist'));
app.use('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
httpServer.listen('8080');
console.log("server is started");
Above build setup was throwing following error ::
Error : Can't find module 'html' -- I'm not sure how to configure Node.Js to refer the angular JS veiw and all the injuctors..
The problem is with this line:
app.set('view engine', 'html');
You are trying to specify view engine with html value, which is not a view engine (expressjs tries to require html module internaly, but doesn't find it). If you need to serve just html files without templating use:
app.use(express.static(__dirname + '/public'));
And move all files you want to serve to public folder.
UPD: you can actually require html file from jade
in views/index.jade
include plain.html
in views/plain.html
<!DOCTYPE html>
...
and app.js can still just render jade:
res.render(index)
Andrew Homeyer's answer
References:
http://expressjs.com/4x/api.html#app.engine
How do I use HTML as the view engine in Express?
http://expressjs.com/guide/using-template-engines.html