I have written the line:
app.engine('hbs',hbs({extanme:'hbs',defaultLayout:'layout',layoutsDir:__dirname+'/views/layout/',partialsDir:__dirname+'/views/partials/'}));
And I have assigned:
var hbs= require('handlebars');
The error I get is:
hbs is not a function
Try something like this
npm i hbs // install hbs package
//app.js
const express = require('express')
const path = require('path')
const hbs = require('hbs')
const app = express()
// View Engine Setup
app.set('views', path.join(__dirname))
app.set('view engine', 'hbs')
app.get('/', function(req, res){
res.render('Home', {
array: ['One', 'Two', 'Three', 'Four'],
message: 'Greetings from geekforgeeks'
})
})
app.listen(8080, function(error){
if(error) throw error
console.log("Server created Successfully")
})
For your app.engine after referencing the NPM express-handlebar docs here: https://www.npmjs.com/package/express-handlebars. You need to add a .engine to your hbs constant.
try this!
var hbs= require('handlebars');
app.engine('hbs', hbs.engine('your config stuff here'));
If your still running into issues. Try using express-handlebars (npm install express express-handlebars) with express, then require them like you do. Then it should work
Try This!!
Add hbs.engine
app.engine('hbs',hbs.engine({extname:'hbs',defaultLayout:'layout',layoutsDir:__dirname+'/views/layout/',partialsDir:__dirname+'/views/partials/'}));
And assign:
var hbs= require('express-handlebars');
Related
This is my server file called app.js and everytime I run node app.js, it gives me an error, "Cannot access 'app' before initialization" Can anyone help me understand why and how I can fix this? Here is my code:
require('dotenv').config();
const path = require('path');
const express = require('express'); // import express package
const app = express();
const homeRouter = require('./routes/home'); //refers to the home.js file in routes
const errorRouter = require('./routes/404'); //refers to the 404.js file in routes
const PORT = process.env.PORT || 3000;
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use('/', (request, response, next) => {
response.send("<h1> Welcome to my Project </h1>");
next();
});
app.use(express.static(path.join(__dirname, 'public')));
app.use(homeRouter);
app.use(errorRouter);
app.listen(PORT);
This code looks fine. Check refering app in router files or share those files so that I can give a look.
Btw, your middleware sending response, so if your router calls res.send or anything like that will cause an error.
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
});
I'm trying to setup a basic mean stack by following this guide, but the client doesn't seem to render the app instead the body contains,
<body>
<app-root></app-root>
</body>
The file structure is exactly the same as a blank angular cli project except the addition of two extra files.
PLUS: npm install --save ejs cors express body-parser
routes/index.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('index.html');
});
module.exports = router;
server.js
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var cors = require('cors')
var index = require('./routes/index');
// app
var app = express();
// cors
app.use(cors());
// views
app.set('views', path.join(__dirname, 'src'));
// engine
app.set('view enginer', 'ejs');
app.engine('html', require('ejs').renderFile);
// angular dist
app.use(express.static(__dirname + '/dist'));
// body bodyParser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
// route
app.use('/', index);
// Initialize the app.
var server = app.listen(process.env.PORT || 3000, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
I run an ng build and node server.js but get a blank white page in the browser.
Perhaps there is a breaking change that I'm not aware of since that guide was using angular2 (I'm using angular 6).
Since your index.html isn't directly inside the dist folder (rather, it is inside a sub-folder for some reason), try changing app.use(express.static(__dirname + '/dist')); to app.use(express.static(__dirname + '/dist/<your project name here>'));
I am trying to use express-handlebars view engine for express and I keep getting the following error:
Error: Cannot find module 'hbs'
at Function.Module._resolveFilename (module.js:538:15)
at Function.Module._load (module.js:468:25)
at Module.require (module.js:587:17)
at require (internal/module.js:11:18)
at new View (C:\Users\WilPrim\Desktop\node-app\node_modules\express\lib\view.js:81:14)
at Function.render (C:\Users\WilPrim\Desktop\node-app\node_modules\express\lib\application.js:570:12)
at ServerResponse.render (C:\Users\WilPrim\Desktop\node-app\node_modules\express\lib\response.js:1008:7)
at C:\Users\WilPrim\Desktop\node-app\routes\routes.js:5:6
at Layer.handle [as handle_request] (C:\Users\WilPrim\Desktop\node-app\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\WilPrim\Desktop\node-app\node_modules\express\lib\router\route.js:137:13)
Here is my Code:
const express = require("express");
const bodyParser = require("body-parser");
const hbs = require("express-handlebars");
const router = require("./routes/routes");
//set up express app
var app = express();
app.use(bodyParser.json());
app.set('view engine', 'hbs');
app.set('views', './views');
app.set('view options', {layout: './layouts/layout'});
app.use(router);
According to the express-handlebars documentation, you have to setup and register the view engine manually:
var express = require('express');
var exphbs = require('express-handlebars');
var app = express();
var hbs = exphbs.create({ /* config */ });
// Register `hbs.engine` with the Express app.
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
// ...still have a reference to `hbs`, on which methods like `loadPartials()`
// can be called.
Looking a little bit further down in the documentation, looks like you can still use the .hbs extension with a bit of configuration:
var express = require('express');
var exphbs = require('express-handlebars');
var app = express();
app.engine('.hbs', exphbs({extname: '.hbs'}));
app.set('view engine', '.hbs');
use command -- sudo npm link hbs
you might have named the main folder as "express"
just change the name of folder,delete "package.json" and try
"npm install" again and then
"npm install express"
"npm install hbs"
/* been using this format for some time now, never had problems */
// import system modules
const hbs = require('express-handlebars');
const express = require('express');
const app = express();
// configuring express-handlebars as hbs
app.engine('hbs', hbs.create({
extname: 'hbs',
defaultLayout: 'main'
}).engine)
// system(app) routes
app.get('/', (req, res, next)=>{
res.render('home', {title: 'HBS TITLE'});
});
// system listening port
app.listen(8080);
install this module on terminal --> npm i hbs
try npm install and npm audit fix multiple times then rum the server after ex
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);