Jade extends not working with express.js - node.js

I don't know what I am doing wrong but extend doesn't working in my case.
server.js
var express = require('express');
var mongodb = require('mongodb');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var expressSession = require('express-session');
var app = require('express')();
app.use(bodyParser());
app.use(cookieParser());
app.use(expressSession({
secret: 'moj-sekret'
}));
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.set('view options', {layout:false});
app.get('/', function(req, res){
res.render('index', { authenticated: false});
console.log('index');
});
app.get('/login', function (req, res){
res.render('login');
console.log('login');
});
app.listen(3000);
example of jade
layout jade
doctype
html
head
title Przykład MongoDB
body
h1 Moja
hr
block content
login jade
extends layout
block content
form(action="/login", method="POST")
fieldset
legend Logowanie
p
label Adres e-mail
input(name="user[email]", type="text")
p
button Wyślij
p
a(href="/") Powrót
i use express 4.7.2 and jade 1.9.1 and i dont have any error or bugs when run node

First of all, your jade file seems to be wrong:
extends layout
block content
form(action="/login", method="POST")
fieldset
legend Logowanie
p
label Adres e-mail
input(name="user[email]", type="text")
p
button Wyślij
p
a(href="/") Powrót
There might be something else as well, but try this first.

Related

How to access cookies in handlebars?

I want to check in home page that user is logged in or not. I have stored jwt token in cookies. For authentication I want to use cookies in handlebars.
Try this code:
Controller
const express = require('express');
const { engine } = require('express-handlebars');
var cookieParser = require('cookie-parser')
const app = express();
app.use(cookieParser())
app.engine('handlebars', engine());
app.set('view engine', 'handlebars');
app.set('views', './views');
app.get('/', (req, res) => {
const isLogin = checkLogin(req.cookies.jwt); // Check login here
res.render('home', { isLogin });
});
View
<h1>{{ isLogin }}</h1>

POST not working while using express + bootstrap modal

I made a register form using the bootstrap modal and I can't seem to make the POST request work.
This is the form in my en.pug file
#register.modal.fade(tabindex="-1" role="dialog" aria-labelledby="register form" aria-hidden="true")
.modal-dialog(role="document")
.modal-content
.modal-header
h5#exampleModalLabel.modal-title Sign Up
button.close(type="button" data-dismiss="modal" aria-label="Close")
span(aria-hidden="true") ×
.modal-body
form(action='/register' method='POST' )
.form-group
label.form-control-label(for="name") Name:
input#name.form-control(type="text", placeholder='first and last' name='name')
.form-group
label.form-control-label(for="email") Email:
input#email.form-control(type="email", placeholder='name#email.com', name='email')
.form-group
label.form-control-label(for="password") Password:
input#password.form-control(type="password" name='password')
.form-group
label.form-control-label(for="password") Confirm Password:
input#confirmed-password.form-control(type="password" name='confirmPassword')
hr.mb-4
// /registration form
.modal-footer
button.btn.btn-secondary(type="button" data-dismiss="modal") Close
button.btn.btn-primary(type="submit") Sign Up
This is my server.js file
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
// serve static files from /public
app.use(express.static(__dirname + '/public'));
app.use(cookieParser());
// view engine setup
app.set('view engine', 'pug');
app.set('views', __dirname + '/views');
// include routes
const routes = require('./routes/index');
app.use('/', routes);
app.listen(3000);
And this is the ./routes/index.js
var express = require('express');
const app = express();
var router = express.Router();
router.get('/', (req, res) => {
const cookie = req.cookies.language;
if (cookie) {
res.render('en', { cookie });
} else {
res.render('ro');
}
});
router.get('/en', function (req, res) {
res.cookie('language');
return res.render('en');
});
// GET /
router.get('/ro', function(req, res) {
res.clearCookie('language');
return res.render('ro');
});
app.post("/register", function (req, res) {
console.log('Hellooooooooooooooooo!')
});
module.exports = router;
When I fill out the form and press the Sign Up button I expect to show "Hellooooooooooooooooo!" in the console but nothing happens and I can't seem to figure out why. Am I missing something here?
EDIT: I figured out that I made a mistake in the pug indentation and the submit button was outside the form, reason for which completing the form and pressing the sign up button didn't do anything
You have to use bodyparser middleware.
We had to install body-parser before express version 4 update, but express now supports body-parser by default.
Just add
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
Hope it helps.
In the HTML, in the input tags of the form of the bootstrap modal window, I used the name attribut (instead of the id attribute) and it is working.
//install body-parser npm and require it
const bodyParser = require('body-parser')
//write code below of app.use(cookieParser()) in server.js
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
router.post('/', function(req, res){
console.log(req.body) //here you will get POST data
})

Why is app.engine not defaulting to layout.hbs as a default

I created a style format with the layout.hbs and notice that all of the pages are not sharing the same consistency in style. I have noticed that I did not declare an app. engine within the app.js. Next, I implemented the app.engine code to set the default layout that is implemented within the layout.hbs
app.engine('hbs', hbs ({extname: 'hbs',defaultLayout: 'layout'}));
An error occurred stating that the layout.hbs cannot be located. I implemented the code again as I noticed I did not direct the folders directories to the layout .hbs. So I implemented the code to
app.engine('hbs', hbs ({extname: 'hbs',defaultLayout: 'layout', layoutsDir:__dirname + '/app_server/views'}));
And the error has disappeared and the default layout structure that has been set to layout.hbs is only showing on the local server index and not the same throughout all of the controllers. I am not too sure what else I am missing
controller and routes code
var express = require('express');
var exphbs = require('express-handlebars');
var router = express.Router();
var ctrlCaribbeanIslands = require('../controllers/CaribbeanIslands')
/* GET home page. */
router.get('/', ctrlCaribbeanIslands.login);
router.get('/blog/add',ctrlCaribbeanIslands.addPost);
router.get('/chat/add',ctrlCaribbeanIslands.addChat);
router.get('/review/add',ctrlCaribbeanIslands.addReview);
router.get('/traceYourTravel', ctrlCaribbeanIslands.tracetravel);
**module.exports = router;**
//controller
module.exports.login = function (req, res) {
res.render('index', { title: 'login'});
};
module.exports.addPost = function(req, res){
res.render('index', { title: 'Add Post' });
};
module.exports.addChat = function(req, res){
res.render('index', { title: 'Add Chat' });
};
module.exports.addReview = function(req, res){
res.render('index', { title: 'Add Review' });
};
module.exports.tracetravel = function(req, res){
res.render('index', { title: 'Trace travel' });
};
app.js
var createError = require('http-errors');
var express = require('express');
var handlebars = require('hbs');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var hbs = require ('express-handlebars');
var indexRouter = require('./app_server/routes/index');
var usersRouter = require('./app_server/routes/users');
var app = express();
app.engine('hbs', hbs ({extname: 'hbs',defaultLayout: 'layout', layoutsDir:__dirname + '/app_server/views'}));
app.set('views', path.join(__dirname, 'app_server','views'));
app.set('view engine', 'hbs');
app.use(express.static(path.join(__dirname, 'public')));
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
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;
#Zrushb Sorry, my bad, it's with app.set, not use. The code should look like this:
const express = require("express"),
hbs = require("hbs"),
mongoose = require("mongoose")
bodyParser = require("body-[arser")
var app = express()
//In ** your database if you need any
mongoose.connect("mongodb:localhost:27017/**")
app.set("view engine", "hbs")
//To get or post
app.set("view engine", "hbs") //Engine HBS
app.set("views", __dirname +"/views") //Folder views (templates)
app.use(express.static("public")) //Public is static (to get .js, images and .css)
app.use('/css',express.static(path.join(__dirname, 'public/stylesheets'))); //Css folder specified (NOT WORKING)
app.use(bodyParser.urlencoded({extended: false})) //Post Body Parser
app.use(bodyParser.json()) //Parser for JSON files
app.use(cookieParser())
hbs.registerPartials(__dirname+ "views/partials")
app.get("/" //etc)
app.post(//etc)
I think express no longer contains handlebars in it, I'd reccomend to download HBS with npm and then require it var hbs = require('hbs')
Then set the view engine to hbs like this -> app.use("view engine", "hbs")
Try that instead of requiring it from express-handlebars, it has worked for me so far.
app.engine('hbs', hbs({
extname: 'hbs',
defaultLayout: 'layout',
layoutsDir:__dirname + '/app_server/views'
}));
change hbs to hbs.engine like this:
app.engine('hbs', hbs.engine({
extname: 'hbs',
defaultLayout: 'layout',
layoutsDir:__dirname + '/app_server/views'
}));
// view engine setup
(01)app.engine('hbs',hbs({extname:'hbs',defaultLayout:'layout',layoutDir:__dirname+'/views/layouts/'}));
(02) app.set('views', path.join(__dirname, 'views'));
(03) app.set('view engine', 'hbs');
change (01) line like this (hbs to hbs.engine):
app.engine('hbs',hbs.engine({extname:'hbs',defaultLayout:'layout',layoutDir:__dirname+'/views/layouts/'}));

ReactJS + Express.js + React-Bootstrap: onClick handler for Bootstrap button not working

I just started learning ReactJS and I can't seem to get the onClick handler to work.
I followed the Express.js application generator tutorial and ended up with the following code.
Can somebody please tell me what's wrong?
//app.js file
var express = require('express');
var path = require('path');
// routes
var launch = require('./routes/launch');
var app = express();
// view engine setup
app.set('views', __dirname + '/views');
app.set('view engine', 'jsx');
app.engine('jsx', require('express-react-views').createEngine());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// attach url to routes
app.use('/', launch);
//launch.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('launch', {});
});
module.exports = router;
//launch.jsx code
var React = require('react');
var DefaultLayout = require('./layouts/default');
// bootstrap
import {Button, Grid, Row, Col, Clearfix, Image, FormGroup, InputGroup, FormControl} from 'react-bootstrap';
var LaunchView = React.createClass({
render: function() {
return (
<FormGroup>
<InputGroup>
<FormControl id="launch-email" type="email" placeholder="Email" />
<InputGroup.Button>
<Button id="launch-submit" className="button-green" onClick={this.handleSubmit}>Submit</Button>
</InputGroup.Button>
</InputGroup>
</FormGroup>
);
},
handleSubmit: function(){
alert("woot");
}
});
module.exports = LaunchView;
doesn't support attaching events on the client-side or doing client-side updates afterwards.
https://github.com/reactjs/express-react-views/issues/2
You can implemented a small "hack" and insert a script file which explicitly sets element's onclick behavior. Keep in mind that DOM has to be loaded in order to attach events.
let myElement = document.getElementsByClassName("overlay")[0];
myElement.addEventListener('click', () => {myElement.style.display = 'none';});
It's not elegant, but it works.

app.post not working node.js

I am new to node and I wanted to try a simple app.post but I can't get it to work. my app.js and index.jade code is shown below. I am trying to get my app to print "hi" to the console when I enter data in the form and press submit but this is not happening.
**app.js**
/**enter code here
* Module dependencies.
*/
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var app = express.createServer();
app.use(express.bodyParser());
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
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());
}
app.get('/', routes.index);
app.get('/users', user.list);
app.get('/george', function(req,res){
res.send('This is the random george page');
console.log("george");
});
app.get('/second', function(req,res){
res.render('secondpage');
});
app.get('/act', function(request, response){
console.log("hello");
});
app.post('/', function(request, response){
console.log("hi");
});
app.listen(3000);
console.log("Express server listening on port 3000");
**index.jade**
extends layout
block content
h1: a(href = 'second') George
p Welcome to your demosite George
form(method="post", action="/", name="act")
p
|Username
input(type="text", name="user")
p
|Password
input(type="text", name="pass")
p
input(type="submit", value="Submit")
First guess is everything in your jade file after the form tag needs 2 more leading spaces indent to make sure the input tags end up nested inside the form tag in the HTML. Your express JS code looks like it should work then.

Resources