I am trying to learn new things with Express and at this moment I would like to be able to show express messages. I added flash, session, and express-messages as dependencies and added messages as a locals variable.
In Pug, I added != messages('message'. locals) and according to the tutorial this should've output a div element with the messages, but unfortunately it throws an error "messages is not a function" when I tried to run it. I suppose req.flash('info','Article Added') in the index.js file on the server side will trigger the message.
this is the screenshot of the error I keep getting
Pls check if I'm getting anything wrong in my code, I'm stuck here. I had tried so much to find out what had caused it.
Here here is my app.js file
const express = require('express');
const path = require('path');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const expressValidator = require('express-validator');
const session = require('express-session');
const flash = require('connect-flash');
mongoose.connect('mongodb://localhost:27017/nodekb', { useNewUrlParser: true });
const db = mongoose.connection;
const app = express();
// app.dynamicHelpers({ messages: require('express-messages') });
//checking for db's connection
db.once('open', () => {
console.log('connected to mongo db');
});
//checking for db errors
db.on('error', (err) => {
console.log(err);
});
//setting up view engine directories
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
//bring in model
let Article = require('./models/articles')
//express routing and using the article model for home page
app.get('/', (req, res) => {
Article.find({}, (err, articles) => {
if (err) {
console.log(err)
} else {
res.render('index', {
title: 'Article',
articles: articles
});
}
});
});
//body parser middleware
app.use(bodyParser.urlencoded({ extended: false }));
// parse application/json
app.use(bodyParser.json());
//seet public folder
app.use(express.static(path.join(__dirname, 'Public')));
//express session middleware
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true
}))
//express message middleware
app.use(flash());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
//
app.use(expressValidator({
errorFormatter: (param, msg, value) => {
var namespace = param.split('.'),
root = namespace.shift(),
formParam = root;
while (namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param: formParam,
msg: msg,
value: value
}
}
}))
//another route to add article
app.get('/article/add', (req, res) => {
res.render('add_article', {
title: 'Add Article'
});
});
//get single article
app.get('/article/:id', (req, res) => {
Article.findById(req.params.id, (err, article) => {
res.render('article', {
article: article
})
return;
});
});
//edit single article
app.get('/article/edit/:id', (req, res) => {
Article.findById(req.params.id, (err, article) => {
res.render('edit_article', {
title: 'Edit Article',
article: article
})
return;
});
});
//submit POST form from add_article.pug
app.post('/article/add', (req, res) => {
let article = new Article();
article.title = req.body.title;
article.author = req.body.author;
article.body = req.body.body;
article.save((err) => {
if (err) {
console.log(err);
} else {
req.flash('info', 'Article Added');
// res.send(article);
res.redirect('/');
}
})
});
//update POST form from edit_article.pug
app.post('/article/add/edit/:id', (req, res) => {
let article = {};
let query = { _id: req.params.id }
article.title = req.body.title;
article.author = req.body.author;
article.body = req.body.body;
Article.update(query, article, (err) => {
if (err) {
console.log(err);
} else {
req.flash('info', 'Article updated');
res.redirect('/');
}
})
});
app.delete('/article/:id', (req, res) => {
let query = { _id: req.params.id }
Article.remove(query, (err) => {
if (err) {
console.log(err);
};
res.send('sucess')
})
})
//setting up port
app.listen(3000, () => {
console.log('runnig on port 3000');
})
module.exports = app;
Here is my layout.pug where i am using the message
doctype html
html
head
title Knowledge base
link(rel='stylesheet', href='/bower_components/bootstrap/dist/css/bootstrap.css')
link(rel='stylesheet', href='/css/style.css')
body
nav.navbar.navbar-dark.bg-dark.navbar-expand-md
a.navbar-brand(href='#') Knowledge Base
button.navbar-toggler(type='button', data-toggle='collapse', data-target='#navbarsExample01', aria-controls='navbarsExample01', aria-expanded='false', aria-label='Toggle navigation')
span.navbar-toggler-icon
#navbarsExample01.collapse.navbar-collapse
ul.navbar-nav.ml-auto.pr-3
li.mr-2
a(href='/') Home
span.sr-only (current)
li.mr-2
a(href='/article/add') Add Articles
.container
!= messages('message', locals)
block content
br
hr
footer
p copyright © 2018
script(src='/bower_components/jquery/dist/jquery.js')
script(src='/bower_components/bootstrap/dist/js/bootstrap.js')
script(src='/js/main.js')
And finally the message.pug file referred to in Layout.pug
.messages
each type in Object.keys({messages})
each message in Object.values({messages})
div(class="alert alert-" +type) #{message}
You need to install the library express-messages
Related
I'm attempting to build my first REST API using MongoDB and Node.
I'm using Postman to test the API.
all of the methods appear to be working, but I currently cannot update any "articles" in my database, using the post method.
I'm essentially trying to edit the "title" and "content" of the articles, but Postman is returning ("update not successful").
//jshint esversion:6
const express = require("express"); //creating four constant, and requiring the modules
const bodyParser = require("body-parser");
const ejs = require("ejs");
const mongoose = require('mongoose');
const app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ //parse requests
extended: true
}));
app.use(express.static("public")); //public directory to store static files
mongoose.connect("mongodb://localhost:27017/wikiDB", { useNewUrlParser: true }); // connect to local database
const articleSchema = { //created article schema
title: String,
content: String
};
const Article = mongoose.model("Article", articleSchema); //created article model
//Requests Targetting all Articles
app.route("/articles")
.get(function (req, res) {
Article.find(function (err, foundArticles) { //search through articles and send to client
if (!err) {
res.send(foundArticles);
} else {
res.send(err);
}
});
})
.post(function (req, res) {
console.log(req.body.title);
console.log(req.body.content);
const newArticle = new Article({
title: (req.body.title),
content: (req.body.content)
});
newArticle.save(function (err) {
if (!err) {
res.send("Successfully added a new article");
} else {
res.send(err);
}
});
})
.delete(function (req, res) {
Article.deleteMany(function (err) {
if (!err) {
res.send("Succesfully deleted all articles.");
} else {
res.send(err);
}
});
});
///request targeting a specific article/////////////////
app.route("/articles/:articleTitle") // match request parameters
.get(function (req, res) {
Article.findOne({ title: req.params.articleTitle },
function (err, foundArticle) {
if (foundArticle) {
res.send(foundArticle);
} else {
res.send("No articles matching that title was found");
}
});
})
.put(function (req, res) {
Article.updateMany(
{ title: req.params.articleTitle },
{ title: req.body.title, content: req.body.content },
{ overwrite: true },
function (err) {
if (!err) {
console.log("success")
res.send("successfully updated article")
} else {
res.send("update not successful");
console.log("error")
}
}
);
});
app.listen(3000, function () {
console.log("Server started on port 3000"); //listen on port
});
Add app.use(bodyParser()); to your code, like this:
app.use(bodyParser());
app.use(bodyParser.urlencoded({extended: true}));
You are supposed to use the update method instead of the updateMany method, as you are updating a single entry in the database.
For information: The body parser you are using is deprecated. If you are using Express >= 4.16.0, then you can use this: express.json() and express.urlencoded() by replacing your body parser code with this:
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
Hope everything works now.
Hey am making a website that will show the articles and the relevant images at the same time. I have already been uploading image files but I cannot show it in my page.
These are my relevant codes:
Article Module:
let mongoose = require('mongoose');
let articleSchema = mongoose.Schema({
title:{
type: String,
required: true
},
author:{
type:String,
required:true
},
body:{
type:String,
required:true
},
img:{
type:String,
required:true
}
});
let Article = module.exports = mongoose.model('Article', articleSchema);
User Module:
let mongoose = require('mongoose');
// User Schema
let UserSchema = mongoose.Schema({
name:{
type: String,
required: true
},
email:{
type: String,
required: true
},
username:{
type: String,
required: true
},
password:{
type: String,
required: true
}
});
let User = module.exports = mongoose.model('User', UserSchema);
Article.js:
const express = require('express');
const router = express.Router();
const multer = require('multer');
// Article Model
let Article = require('../models/article');
// User Model
let User = require('../models/user');
router.get('/sonuc', function(req, res){
if(req.query.search) {
const regex = new RegExp(escapeRegex(req.query.search), 'gi');
Article.find({"title": regex}, function(err, articles) {
if(err) {
console.log(err);
} else {
res.render("sonuc", {
articles: articles
});
}
});
}
});
function escapeRegex(text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
};
// Add Route
router.get('/add', ensureAuthenticated, function(req, res){
res.render('add_article', {
title:'Add Article'
});
});
const upload = multer({dest: __dirname + '/uploads'});
// Add Submit POST Route
router.post('/add',upload.single('img'), function(req, res){
req.checkBody('title','Title is required').notEmpty();
//req.checkBody('author','Author is required').notEmpty();
req.checkBody('body','Body is required').notEmpty();
// Get Errors
let errors = req.validationErrors();
if(errors){
res.render('add_article', {
title:'Add Article',
errors:errors
});
} else {
var article = new Article({
title: req.body.title,
author: req.user._id,
img: '/uploads/' + req.file.filename,
body: req.body.body,
});
article.save(function(err){
if(err){
console.log(err);
return;
} else {
res.render('add_article', {
});
}
});
}
});
// Load Edit Form
router.get('/edit/:id', ensureAuthenticated, function(req, res){
Article.findById(req.params.id, function(err, article){
/*if(article.author != req.user._id){
req.flash('danger', 'Not Authorized');
return res.redirect('/');
}*/
res.render('edit_article', {
title:'Edit Article',
article:article
});
});
});
// Update Submit POST Route
router.post('/edit/:id', function(req, res){
let article = {};
article.title = req.body.title;
article.author = req.body.author;
article.body = req.body.body;
let query = {_id:req.params.id}
Article.update(query, article, function(err){
if(err){
console.log(err);
return;
} else {
req.flash('success', 'Article Updated');
res.redirect('/');
}
});
});
// Delete Article
router.delete('/:id', function(req, res){
if(!req.user._id){
res.status(500).send();
}
let query = {_id:req.params.id}
Article.findById(req.params.id, function(err, article){
if(article.author != req.user._id){
res.status(500).send();
} else {
Article.remove(query, function(err){
if(err){
console.log(err);
}
res.send('Success');
});
}
});
});
// Get Single Article
router.get('/:id', function(req, res){
Article.findById(req.params.id, function(err, article){
//User.findById(article.author, function(err, user){
res.render('article', {
article:article,
imagePath: user.img,
author: user.name
});
});
});
//});
// Access Control
function ensureAuthenticated(req, res, next){
if(req.isAuthenticated()){
return next();
} else {
req.flash('danger', 'Please login');
res.redirect('/users/login');
}
}
module.exports = router;
article.pug:
extends layout
block content
br
h1= article.title
//h5 Written by #{author}
p= article.body
img(src=imagePath, alt='img')
hr
if user
if user.id ==article.author
a.btn.btn-default(href='/articles/edit/'+article._id) Edit
a.btn.btn-danger.delete-article(href='#',data-id=article._id) Delete
Still I cannot understan why that these codes are not working. I am waiting your supports. Every answer will be appreciated.
My App.js:
const express = require('express');
const ejs = require('ejs');
const path = require('path');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const expressValidator = require('express-validator');
const flash = require('connect-flash');
const session = require('express-session');
const passport = require('passport');
config = require('./config/database');
const multer = require('multer');
mongoose.connect(config.database);
let db = mongoose.connection;
// Check connection
db.once('open', function(){
console.log('Connected to MongoDB');
});
// Check for DB errors
db.on('error', function(err){
console.log(err);
});
// Init App
const app = express();
// Bring in Models
let Article = require('./models/article');
// EJS
app.set('view engine', 'ejs');
// Public Folder
app.use(express.static('./public'));
// Load View Engine
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// Body Parser Middleware
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
// parse application/json
app.use(bodyParser.json());
// Set Public Folder
app.use(express.static(path.join(__dirname, 'public')));
// Express Session Middleware
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true
}));
// Express Messages Middleware
app.use(require('connect-flash')());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
// Express Validator Middleware
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
// Passport Config
require('./config/passport')(passport);
// Passport Middleware
app.use(passport.initialize());
app.use(passport.session());
app.get('*', function(req, res, next){
res.locals.user = req.user || null;
next();
});
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
})
const upload = multer({ storage: storage })
// Check File Type
function checkFileType(file, cb){
// Allowed ext
const filetypes = /jpeg|jpg|png|gif/;
// Check ext
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
// Check mime
const mimetype = filetypes.test(file.mimetype);
if(mimetype && extname){
return cb(null,true);
} else {
cb('Error: Images Only!');
}
}
// Home Route
app.get('/', function(req, res){
Article.find({}, function(err, articles){
if(err){
console.log(err);
} else {
res.render('index', {
title:'Articles',
articles: articles
});
}
});
});
app.get('/sonuc', function(req, res){
if (req.query.search) {
const regex = new RegExp(escapeRegex(req.query.search), 'gi');
Article.find({"title": regex}, function(err, articles) {
if(err) {
console.log(err);
} else {
res.render("index", {
articles: articles
});
}
});
}
});
function escapeRegex(text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
};
// Route Files
let articles = require('./routes/articles');
let users = require('./routes/users');
app.use('/articles', articles);
app.use('/users', users);
// Start Server
app.listen(3000, function(){
console.log('Server started on port 3000...');
});
You have to pass in the path to the img tag for it to render your image.
You have specified /upload to be the folder, so just put that into the src attribute of the img tags.
extends layout
block content
br
h1= article.title
//h5 Written by #{author}
p= article.body
img(src=imagePath, alt='img')
GET route fix:
Article.findById(req.params.id, function(err, article){
//You commented this line that's why user is undefined
User.findById(article.author, function(err, user){
res.render('article', {
article:article,
imagePath: article.img, //Should be article.img
author: user.name
})
I am trying to combine my CRUD and TODO application. However, I received this error even though I have added the "module.exports = router;" to my routes js files, server.js file and controller js files. I will add these files below and my folder file structure. Have I missed something?
folder/file structure
server.js file
require('./models/db');
require('./models/task');
const express = require('express');
const path = require('path');
const exphbs = require('express-handlebars');
const bodyparser = require('body-parser');
const logger = require('morgan');
const mongoose = require('mongoose');
const favicon = require('serve-favicon');
const employeeController = require('./controllers/employeeController');
var app = express();
//setting up morgan middleware
app.use(logger('dev'));
app.use(bodyparser.urlencoded({
extended: true
}));
app.use(bodyparser.json());
app.set('views', path.join(__dirname, '/views/'));
app.engine('hbs', exphbs({ extname: 'hbs', defaultLayout: 'mainLayout', layoutsDir: __dirname + '/views/layouts/' }));
app.set('view engine', 'hbs');
//serving blank favicon to keep from throwing 404 errors
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')))
//setting up static path for serving static files
app.use(express.static(path.join(__dirname, 'public')));
//Bringing in the routes
const index = require('./routes/index');
const api = require('./routes/api');
app.use('/', index);
app.use('/api', api);
app.listen(3000, () => {
console.log('Express server started at port : 3000');
});
app.use('/employee', employeeController);
module.exports = router;
employeeController.js file
const express = require('express');
var router = express.Router();
const mongoose = require('mongoose');
const Employee = mongoose.model('Employee');
const Task = require('../models/task');
router.get('/', (req, res) => {
res.render("employee/addOrEdit", {
viewTitle: "Insert Module"
});
});
router.get('/test', (req, res) => {
res.render("employee/test");
});
router.get('/edit', (req, res) => {
res.render("edit");
});
router.get('/index', function(req, res) {
res.render('employee/index', {layout: 'main.hbs'});
});
router.get('/edit', function(req, res) {
res.render('employee/edit', {layout: 'main.hbs'});
});
router.post('/', (req, res) => {
if (req.body._id == '')
insertRecord(req, res);
else
updateRecord(req, res);
});
function insertRecord(req, res) {
var employee = new Employee();
employee.fullName = req.body.fullName;
employee.module = req.body.module;
employee.mobile = req.body.mobile;
employee.city = req.body.city;
employee.save((err, doc) => {
if (!err)
res.redirect('employee/list');
else {
if (err.name == 'ValidationError') {
handleValidationError(err, req.body);
res.render("employee/addOrEdit", {
viewTitle: "Insert Module",
employee: req.body
});
}
else
console.log('Error during record insertion : ' + err);
}
});
}
function updateRecord(req, res) {
Employee.findOneAndUpdate({ _id: req.body._id }, req.body, { new: true }, (err, doc) => {
if (!err) { res.redirect('employee/list'); }
else {
if (err.name == 'ValidationError') {
handleValidationError(err, req.body);
res.render("employee/addOrEdit", {
viewTitle: 'Update Module',
employee: req.body
});
}
else
console.log('Error during record update : ' + err);
}
});
}
router.get('/list', (req, res) => {
Employee.find((err, docs) => {
if (!err) {
res.render("employee/list", {
list: docs
});
}
else {
console.log('Error in retrieving module list :' + err);
}
});
});
function handleValidationError(err, body) {
for (field in err.errors) {
switch (err.errors[field].path) {
case 'fullName':
body['fullNameError'] = err.errors[field].message;
break;
case 'module':
body['moduleError'] = err.errors[field].message;
break;
default:
break;
}
}
}
router.get('/:id', (req, res) => {
Employee.findById(req.params.id, (err, doc) => {
if (!err) {
res.render("employee/addOrEdit", {
viewTitle: "Update Module",
employee: doc
});
}
});
});
router.get('/delete/:id', (req, res) => {
Employee.findByIdAndRemove(req.params.id, (err, doc) => {
if (!err) {
res.redirect('/employee/list');
}
else { console.log('Error in module delete :' + err); }
});
});
const sortTask = (a,b) => {
const taskA = a.task.toLowerCase();
const taskB = b.task.toLowerCase();
return (taskA < taskB) ? -1 : (taskA > taskB) ? 1 : 0;
}
module.exports = {
findAll: function (req,res){
Task
.find({})
.then(result => {
result.sort(sortTask)
res.render('employee/index', {layout: 'main.hbs'}, {tasks: result})
})
.catch(err => res.json(err))
},
create: function(req,res){
Task
.create(req.body)
.then(result => {
// result.sort(sortTask)
res.json(result)
})
.catch(err => res.json(err));
},
findOne: function (req,res){
Task
.findOne({_id: req.params.id})
.then(result => res.render('employee/edit', {layout: 'main.hbs'}, result))
.catch(err => res.json(err))
},
complete: function (req,res){
Task
.findOneAndUpdate({_id: req.params.id}, {completed: true})
.then(result => res.json(result))
.catch(err => res.json(err))
},
deleteOne: function (req,res){
Task
.remove({_id: req.params.id})
.then(result => res.json(result))
.catch(err => res.json(err))
},
updateName: function (req,res){
Task
.findOneAndUpdate({_id: req.body._id}, {task: req.body.task})
.then(result => res.json(result))
.catch(err => res.json(err))
}
}
module.exports = router;
api.js file
const router = require('express').Router();
const taskController = require('../controllers/employeeController');
router
.route('/task/:id')
.get(taskController.findOne)
.put(taskController.complete)
.delete(taskController.deleteOne)
router.post('/create', taskController.create);
router.post('/update', taskController.updateName);
module.exports = router;
index.js file
const router = require('express').Router();
const taskController = require('../controllers/employeeController');
router.get('/', taskController.findAll)
module.exports = router;
You are using module.exports = {...} multiple times in employeeController.js and this is not how it works, please see the docs to learn more
To fix this just add the router to the first exported object like this:
module.exports = {
findAll: function (req,res) {
...
},
// rest of the functions
updateName: function(req,res) {
...
},
router
}
̶m̶o̶d̶u̶l̶e̶.̶e̶x̶p̶o̶r̶t̶s̶ ̶=̶ ̶r̶o̶u̶t̶e̶r̶;̶
And then in server.js use the router like this:
app.use('/employee', employeeController.router);
I have implemented a CRUD application similar to the one in this link - https://www.youtube.com/watch?v=voDummz1gO0&t=1445s and a TODO application similar to the one in this link - https://medium.com/#atingenkay/creating-a-todo-app-with-node-js-express-8fa51f39b16f. I added a href link in the addOrEdit.hbs page to index.ejs, both in the views folder and have added the code from the TODO to the CRUD. I then start the server using a bat file, mongodb compass community and node server.js, everything connects fine but I receive this error - "Failed to lookup view "employee/addOrEdit" in views directory..." Is this because I have added some code incorrectly to my server.js file or controller file. I thought it might be due the server.js file having the following - "app.set('view engine', 'hbs');
app.set('view engine', 'ejs');" as I do not know if its possible to set view engines as both hbs and ejs. Below is my code and folder/file structure, hope it helps!
Folder/file structure
server.js file
require('./models/db');
const express = require('express');
const path = require('path');
const exphbs = require('express-handlebars');
const bodyparser = require('body-parser');
const employeeController = require('./controllers/employeeController');
var app = express();
app.use(bodyparser.urlencoded({
extended: true
}));
app.use(bodyparser.json());
app.set('views', path.join(__dirname, '/views/'));
app.engine('hbs', exphbs({ extname: 'hbs', defaultLayout: 'mainLayout', layoutsDir: __dirname + '/views/layouts/' }));
app.set('view engine', 'hbs');
app.set('view engine', 'ejs');
//render css files
app.use(express.static("public"));
app.listen(3000, () => {
console.log('Express server started at port : 3000');
});
app.use('/employee', employeeController);
employeeController.js file in the controller file
const express = require('express');
var router = express.Router();
const mongoose = require('mongoose');
const Employee = mongoose.model('Employee');
//placeholders for added task
var task = ["complete presentation", "practise with nodejs"];
//placeholders for removed task
var complete = ["finish jquery"];
router.get('/', (req, res) => {
res.render("employee/addOrEdit", {
viewTitle: "Insert Module"
});
});
router.get('/test', (req, res) => {
res.render("employee/test");
});
//render the ejs and display added task, completed task
router.get("/index", function(req, res) {
res.render("index", { task: task, complete: complete });
});
router.post('/', (req, res) => {
if (req.body._id == '')
insertRecord(req, res);
else
updateRecord(req, res);
});
function insertRecord(req, res) {
var employee = new Employee();
employee.fullName = req.body.fullName;
employee.module = req.body.module;
employee.mobile = req.body.mobile;
employee.city = req.body.city;
employee.save((err, doc) => {
if (!err)
res.redirect('employee/list');
else {
if (err.name == 'ValidationError') {
handleValidationError(err, req.body);
res.render("employee/addOrEdit", {
viewTitle: "Insert Module",
employee: req.body
});
}
else
console.log('Error during record insertion : ' + err);
}
});
}
function updateRecord(req, res) {
Employee.findOneAndUpdate({ _id: req.body._id }, req.body, { new: true }, (err, doc) => {
if (!err) { res.redirect('employee/list'); }
else {
if (err.name == 'ValidationError') {
handleValidationError(err, req.body);
res.render("employee/addOrEdit", {
viewTitle: 'Update Module',
employee: req.body
});
}
else
console.log('Error during record update : ' + err);
}
});
}
router.get('/list', (req, res) => {
Employee.find((err, docs) => {
if (!err) {
res.render("employee/list", {
list: docs
});
}
else {
console.log('Error in retrieving module list :' + err);
}
});
});
function handleValidationError(err, body) {
for (field in err.errors) {
switch (err.errors[field].path) {
case 'fullName':
body['fullNameError'] = err.errors[field].message;
break;
case 'module':
body['moduleError'] = err.errors[field].message;
break;
default:
break;
}
}
}
router.get('/:id', (req, res) => {
Employee.findById(req.params.id, (err, doc) => {
if (!err) {
res.render("employee/addOrEdit", {
viewTitle: "Update Module",
employee: doc
});
}
});
});
router.get('/delete/:id', (req, res) => {
Employee.findByIdAndRemove(req.params.id, (err, doc) => {
if (!err) {
res.redirect('/employee/list');
}
else { console.log('Error in module delete :' + err); }
});
});
//post route for adding new task
router.post("/addtask", function(req, res) {
var newTask = req.body.newtask;
//add the new task from the post route
task.push(newTask);
res.redirect("/");
});
router.post("/removetask", function(req, res) {
var completeTask = req.body.check;
//check for the "typeof" the different completed task, then add into the complete task
if (typeof completeTask === "string") {
complete.push(completeTask);
//check if the completed task already exits in the task when checked, then remove it
task.splice(task.indexOf(completeTask), 1);
} else if (typeof completeTask === "object") {
for (var i = 0; i < completeTask.length; i++) {
complete.push(completeTask[i]);
task.splice(task.indexOf(completeTask[i]), 1);
}
}
res.redirect("/");
});
module.exports = router;
I am trying to link (href) my hbs page to a ejs page in my views folder. I have installed consolidate as seen in other tutorials via going to the directory npm install consolidate and have added the code var engines = require('consolidate'); and app.engine('handlebars', engines.handlebars); to my code but nothing works (I also know if you’re using “.ejs” extensions you don’t need to do anything). Can someone please help me out as I cannot view my pages due to this. I receive this error - "Failed to lookup view employee/addOrEdit in views directory...". I have added my folder/file structure below and code snippets. Thank you!
folder/file structure
server.js file
require('./models/db');
const express = require('express');
const path = require('path');
const exphbs = require('express-handlebars');
const bodyparser = require('body-parser');
var engines = require('consolidate');
const employeeController = require('./controllers/employeeController');
var app = express();
app.engine('handlebars', engines.handlebars);
app.use(bodyparser.urlencoded({
extended: true
}));
app.use(bodyparser.json());
app.set('views', path.join(__dirname, '/views/'));
app.engine('hbs', exphbs({ extname: 'hbs', defaultLayout: 'mainLayout', layoutsDir: __dirname + '/views/layouts/' }));
app.set('view engine', 'hbs');
//render css files
app.use(express.static("public"));
app.listen(3000, () => {
console.log('Express server started at port : 3000');
});
app.use('/employee', employeeController);
employeeController.js file
const express = require('express');
var router = express.Router();
const mongoose = require('mongoose');
const Employee = mongoose.model('Employee');
//placeholders for added task
var task = ["complete presentation", "practise with nodejs"];
//placeholders for removed task
var complete = ["finish jquery"];
router.get('/', (req, res) => {
res.render("employee/addOrEdit", {
viewTitle: "Insert Module"
});
});
router.get('/test', (req, res) => {
res.render("employee/test");
});
//render the ejs and display added task, completed task
router.get("/index", function(req, res) {
res.render("index", { task: task, complete: complete });
});
router.post('/', (req, res) => {
if (req.body._id == '')
insertRecord(req, res);
else
updateRecord(req, res);
});
function insertRecord(req, res) {
var employee = new Employee();
employee.fullName = req.body.fullName;
employee.module = req.body.module;
employee.mobile = req.body.mobile;
employee.city = req.body.city;
employee.save((err, doc) => {
if (!err)
res.redirect('employee/list');
else {
if (err.name == 'ValidationError') {
handleValidationError(err, req.body);
res.render("employee/addOrEdit", {
viewTitle: "Insert Module",
employee: req.body
});
}
else
console.log('Error during record insertion : ' + err);
}
});
}
function updateRecord(req, res) {
Employee.findOneAndUpdate({ _id: req.body._id }, req.body, { new: true }, (err, doc) => {
if (!err) { res.redirect('employee/list'); }
else {
if (err.name == 'ValidationError') {
handleValidationError(err, req.body);
res.render("employee/addOrEdit", {
viewTitle: 'Update Module',
employee: req.body
});
}
else
console.log('Error during record update : ' + err);
}
});
}
router.get('/list', (req, res) => {
Employee.find((err, docs) => {
if (!err) {
res.render("employee/list", {
list: docs
});
}
else {
console.log('Error in retrieving module list :' + err);
}
});
});
function handleValidationError(err, body) {
for (field in err.errors) {
switch (err.errors[field].path) {
case 'fullName':
body['fullNameError'] = err.errors[field].message;
break;
case 'module':
body['moduleError'] = err.errors[field].message;
break;
default:
break;
}
}
}
router.get('/:id', (req, res) => {
Employee.findById(req.params.id, (err, doc) => {
if (!err) {
res.render("employee/addOrEdit", {
viewTitle: "Update Module",
employee: doc
});
}
});
});
router.get('/delete/:id', (req, res) => {
Employee.findByIdAndRemove(req.params.id, (err, doc) => {
if (!err) {
res.redirect('/employee/list');
}
else { console.log('Error in module delete :' + err); }
});
});
//post route for adding new task
router.post("/addtask", function(req, res) {
var newTask = req.body.newtask;
//add the new task from the post route
task.push(newTask);
res.redirect("/");
});
router.post("/removetask", function(req, res) {
var completeTask = req.body.check;
//check for the "typeof" the different completed task, then add into the complete task
if (typeof completeTask === "string") {
complete.push(completeTask);
//check if the completed task already exits in the task when checked, then remove it
task.splice(task.indexOf(completeTask), 1);
} else if (typeof completeTask === "object") {
for (var i = 0; i < completeTask.length; i++) {
complete.push(completeTask[i]);
task.splice(task.indexOf(completeTask[i]), 1);
}
}
res.redirect("/");
});
module.exports = router;
You need to add both engines, ejs and express-handlebars in your package.json file
npm i ejs
npm i express-handlebars
Import dependency in Server.js file
const ejs = require('ejs');
const exhbs = require('express-handlebars');
Set engine to your server.js file
app.set('view engine', 'ejs');
app.engine('handlebars', exhbs());
app.set('view engine', 'handlebars');
For rendering template, you need to set the file extension
res.render('heyy.handlebars');
res.render('index.ejs');
This is your Folder Structure
Inside main.handlebars and inside body add {{{body}}} inorder to mark where layout should insert page