Node js : Using Handlebars and Bodyparser together - javascript

In this basic program I would like to get user input using 'body parser' and then enter that input via handlebars onto the index page. I have attempted many times but can't seem to acheive it. Also does handlebars and bodyparser go together or should I be using something different.
Template:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
<header>
<h1>Bodyparser and Handlebars</h1>
</header>
<form method="post" action="/">
<input type="text" name="name1">
<input type="submit" value="Submit">
</form>
{{test}}
</body>
</html>
Node.js
var express = require('express');
var app = express();
var handlebars = require('express-handlebars');
var path = require("path");
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.set('view engine', 'html');
app.engine('html', handlebars({
defaultLayout: 'base',
extname: '.html'
}));
app.use(express.static(path.join(__dirname, 'public'))); //public directory
app.get('/index', function(req, res) {
res.sendFile('index.html', { root: __dirname });
});
app.get('/', function (req, res) {
res.render('index', {
test: req.body.name1});
});
app.post('/', function(req, res){
console.log(req.body.name1);
});
app.listen(3000);

Your post to / should be:
app.post('/', function(req, res){
res.render('index', {
test: req.body.name1});
});
And you are done.

Body-parser and handlebars work perfect togheter. Body-parser allows you to collect the request data inside the router controller and handlebars is a template engine that render the variables and more stuff.
You need to pass the text that you want to display to the POST router controller.
<form action="/" method="post">
name1: <input type="text" name="name1"><br>
<input type="submit" value="Submit">
</form>
Put that form in other view or anywhere you want
Inside the controller pass the request parameter to handlebars:
app.post('/', function(req, res){
res.render('index', {
test: req.body.name1});
});

Related

Node.js/Express.js request body is undefined. body-parser is installed and imported

I am trying to get the text that is typed in by the user in my html input field and push it into an array. But the body of my request ist always empty. I already tried changing the order of code but it is not helping. Where is the Problem?
app.js file:
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const gameRouter = require('./routes/game.js');
const siteRouter = require('./routes/site.js');
const app = express();
app.set('view engine', 'ejs');
app.set('views', 'views');
app.use(bodyParser.urlencoded({extended: false}));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/game', gameRouter);
app.use('/', siteRouter);
app.listen(3000);
game.js file in the folder routes:
const express = require('express');
const router = express.Router();
const games = [];
router.get('/game', (req, res, next) => {
});
router.post('/create', (req, res, next) => {
console.log(req.body);
games.push({game: req.body.game})
res.redirect('/');
})
module.exports = router;
ejs file for html generating:
<%- include('./includes/head.ejs') %>
</head>
<body>
<%- include('./includes/nav.ejs') %>
<h1>Create a new Game</h1>
<main>
<form action="/game/create" method="POST">
<div>
<input type="text" id="game">
<button type="submit">start</button>
</div>
</form>
</main>
<%- include('./includes/end.ejs') %>
You need to add name attribute to the input element:
<input type="text" name="game" id="game">
Use this line before app.use():
// For parsing a JSON file
app.use(bodyParser.json())
// For parsing parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: false}));

Unable to render JSON in html - node.js

This is probably a simple solution, however I cannot figure out how to carry my JSON object over to my view. Normally you'd throw JSON into res.render() inside your app.get .. unfortunately I am having trouble. A problem arises because i need to be able to send form data from html to my API request, then grab that JSON object and display it in my view. I can see it in my console, but unable to carry it over to html. Would love some help or guidance on how to improve my code or find a solution. Any help is appreciated! - View code below:
Server.js
var path = require('path');
var express = require('express');
var exphbs = require('express-handlebars');
var bodyParser = require('body-parser');
var Bls2 = require('bls2');
var app = express();
app.engine('html', exphbs({ extname: '.html' }));
app.set('view engine', 'html');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
var blsRequest = function(req, res, inputContent){
const API_KEY = //bls API key here
let bls = new Bls2(API_KEY);
console.log('this is seriesID =', inputContent);
let options = {
'seriesid': [inputContent],
'startyear': '2008',
'endyear': '2018',
// ...
};
bls.fetch(options).then(function (response) {
var data = JSON.stringify(response)
console.log(data);
console.log('API Call Complete')
res.send({data : data}); //need to render home view and JSON HERE
});
}
app.get('/', function (req, res) {
res.render('home');
});
app.post('/', function(req, res){
let inputContent = req.body.seriesID;
blsRequest(req, res, inputContent);
});
app.listen(8000);
html
<!DOCTYPE html>
<html>
<head>
<title>LBS</title>
<meta charset="utf-8">
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="crossorigin="anonymous"></script>
</head>
<body>
<div class="container-fluid">
<form id="seriesID">
<div class="form-group" method="post" action='/'>
<label for="seriesID">Input Series ID</label>
<input type="text" class="form-control" name="seriesID" placeholder="Series ID">
</div>
<button class="btn btn-primary" type="submit" >Search</button>
</form><br>
uhh JSON should be here: {{data}}
</div>
</body>
<script type="text/javascript">
$("#seriesID").submit(function (event) {
$.post('/', $("#seriesID").serialize(), function (data) {
//data is the response from the backend
});
event.preventDefault();
});
</script>
</html>
use res.render('home',{data});
because your{{data}} is undefined that's why it is not printing anything
it is even better to use {{JSON.stringify(data)}}

Use express js to pass form data to new page

I'm still fairly new to Express.js. I have a question about sending form data to an existing template. I have two routes which have template views associated with them. One page has a form on it and I want to take inputs from that form to populate the other template of the other route. I'm using Hanglebars for my template engine.
I've found a lot of helpful answers here (this one especially Cannot POST form node.js - express ), but none that quite answer my question.
I know how to post to create a new page with the form data. Like this:
router.post('/game', function(req, res) {
res.send(req.body.username);
});
But how do I get req.body.username accessible to a handlebars template? I've been reading various tutorials and it looks like I need to do something with next() in app.use('/game', game);. But I'm getting lost as to what exactly that is.
Here's a simplified version of my code.
My main server file:
var express = require('express');
var exphbs = require('express-handlebars');
var app = express();
var http = require('http').Server(app);
var path = require('path');
var io = require('socket.io')(http);
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var routes = require('./routes/index');
var game = require('./routes/game');
app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/game', game);
// view engine setup
app.set('views', path.join(__dirname, 'views'));
http.listen(3000, function(){
console.log('listening on *:3000');
});
My route file "index.js":
var express = require('express');
var exphbs = require('express-handlebars');
var app = express();
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
res.render('index', {
title: 'Pick a Player',
});
});
module.exports = router;
Here is the form on index.handlebars (just the form):
<form method="post" action="/game" novalidate name="pick-a-player" id="pickAPlayer" class="form-box">
<p>What is your name?</p>
<input type="text" name="username" placeholder="name">
<p>Please select a player</p>
<label>
<input type="radio" name="player" value="Jane" checked> Jane<br>
<input type="radio" name="player" value="Sue"> Sue<br>
<input type="radio" name="player" value="Anne"> Anne<br>
</label>
<input type="submit" value="Start the game" id="submitCharacterForm">
</form>
I know I need to use post to get the data through req.body. But I'm getting the template through .get(). How do get the two to communicate?
Here's the route for game.js
var express = require('express');
var exphbs = require('express-handlebars');
var app = express();
var router = express.Router();
/* GET Game page. */
router.get('/', function(req, res) {
res.render('game', {
title: 'Let's Play',
username: req.body.username,
player: req.body.player
});
});
module.exports = router;
When the value of player gets called on game.handlebars, it looks like this:
<p class="player-card">{{player}}</p>
If I'm understanding this correctly, the main form will have two values on the request body: username and player.
This form will make a POST request to /game according to your form block:
<form method="post" action="/game" ...>
You handle this POST request with the following route handler:
router.post('/game', function(req, res) {
res.send(req.body.username);
});
And you want to send the username and player values to your game template correct?
If I'm understanding this correctly, you can either res.redirect with data or simply render a different view with the data:
router.post('/game', (req, res) => {
const { username, player } = req.body
res.render('play-game', { username, player });
});

Render html with node.js

I am really new to the whole MEAN-stack and are trying to create an application on openshift but are unable to render a new page.
I just keep getting this error and can't solve it with anything I've googled.
My Error: Failed to lookup view "/register" in public directory
It works completely fine to render the index page with app.get('/', func()) in server.js and tried to to the exact same thing with app.get('/register). I used to have the same problem with '/' at first but solved it using app.use(express.static(__dirname + '/public'));
Both index.html and register.html are located in the public directory.
These are extracts of my code:
index.html
<body ng-app="">
<div class="container" ng-controller="LoginController" >
<h1>Logg in</h1>
<input class="form-control" placeholder="ID"/>
<input class="form-control" placeholder="Password"/>
<button class="btn">Logga in</button>
<button ng-click="open()" class="btn">Register User</button>
</div>
</body>
logincontroller
function LoginController($scope, $http) {
console.log("Hello from Login");
$scope.open = function () {
console.log('open i login.js');
$http.get('/register')
};
};
server.js
var express = require('express');
var fs = require('fs');
var mongojs = require('mongojs');
var jade = require('jade')
var app = express();
var cors = require('cors');
var bodyParser = require('body-parser');
app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser());
app.get('/env',function(req, res){
res.json(process.env);
});
app.get('/', function (req, res) {
res.render('/index', {});
});
app.get('/register', function (req, res) {
res.render('/register');
});
app.set('view engine', 'jade');
There are a couple of issues.
1) Don't use a slash for the 'register' file. This is a file in the /public folder, not a folder or route.
app.get('/register', function (req, res) {
res.render('register');
});
2) You have set jade as your rendering engine. This means you will be serving .jade files. Your public folder should have index.jade. And it should look like this:
html
body(ng-app='')
.container(ng-controller='LoginController')
h1 Logg in
input.form-control(placeholder='ID')
input.form-control(placeholder='Password')
button.btn Logga in
button.btn(ng-click='open()') Register User
A couple of notes:
Jade is a HTML templating engine, it's relatively straight forward, see http://jade-lang.com/tutorial/.
There is express-generator which will give you an example app, it's an excellent starting point: http://expressjs.com/en/starter/generator.html
By the way, there is also an HTML-2-Jade converter, I find this helpful sometimes: http://html2jade.org/

node.js variables will not be parsed

i am new in node.js and express.
in my test app the html variables will not be parsed.
what is the problem?
server.js
enter var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({
extended : true
}));
app.use(express.static(__dirname));
app.get('/', function(req, res) {
res.render('index', {
wert : 'hallo'
});
});
app.post('/', function(req, res) {
var wert = req.body.wert;
var html = 'Hallo: '+wert+'!\n'
+ 'Mach\'s nochmal!';
res.send(html);
});
app.listen(8882);
console.log('Server port: 8882');
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Startseite</title>
</head>
<body>
<p>Hallo <%= wert %>, dies ist mein kleiner Webserver!</p>
<br>
<form action="/" method="post">
<input type="text" width="40" name="wert" value="<%= wert %>">
<input type="submit" value="submit">
</form>
</body>
</html>
the value parameter <%= wert %> in the view is not parsed.
why? how to do it?
thank you
jet
Express doesn't come with a view-engine by default. You need to add one, in your case EJS.
Using the command line, type:
npm install ejs
server.js now becomes:
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.engine('.html', require('ejs').__express);
app.set('views', __dirname + '/views');
app.set('view engine', 'html');
app.use(bodyParser.urlencoded({
extended : true
}));
app.use(express.static(__dirname));
app.get('/', function(req, res) {
res.render('index', {
wert: 'hallo'
});
});
app.post('/', function(req, res) {
var wert = req.body.wert;
res.render('index', {
wert: wert
});
});
app.listen(8882);
thank you ben,
your ejs configuration was good.
I had to install express, ejs, body-parser. that was ok.
then i had to remove the line with app.use(express.static(__dirname));
and i had to change
app.set('views', __dirname + '/views');
to
app.set('views', __dirname);
for my original path.
then everything was ok!
greez
jet

Categories