How to get GET multiple variables in Express.js on Node.js? - javascript

I am trying to get Form data from html page to Node Js server .
My html file is index.html
<body>
<nav>
<ul>
<li>
Add Product
<div class="dialog" style="display:none">
<div class="title">Add Product</div>
<form action="" method="get">
<input id = "name" name="name" type="text" placeholder="Product Name"/>
<input name="code" type="text" placeholder="Product Code"/>
<input name="category" type="text" placeholder=" Category"/>
<input name="brand" type="text" placeholder="Brand"/>
<input type="submit" value="Ok"/>
</form>
</div>
</li>
<li class="radio">
</li>
</ul>
</div>
</nav>
<p></p>
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src="js/index.js"></script>
</body>
after submitting the form there is no action perform by the server just get the url with all details
and My server is server.js
var express = require("express"),
app = express(),
bodyParser = require('body-parser'),
errorHandler = require('errorhandler'),
methodOverride = require('method-override'),
hostname = process.env.HOSTNAME || 'localhost',
port = parseInt(process.env.PORT, 10) || 4004,
publicDir = process.argv[2] || __dirname + '/public';
var exec = require('child_process').exec;
var fs = require('fs');
//Show homepage
app.get("/", function (req, res) {
res.redirect("/index.html");
console.log("shubh ");
});
app.get("/index/", function (req, res) {
res.redirect("/index.html");
console.log("shubham ");
});
app.get("/index/:name", function (req, res){
console.log("shubham batra");
var keyword = req.query.code;
console.log(keyword);
//res.send('You sent the name "' + req.body.name + '".');
console.log(res.body);
});
app.use(errorHandler({
dumpExceptions: true,
showStack: true
}));
//Search page
app.use(methodOverride());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(express.static(publicDir));
app.use(errorHandler({
dumpExceptions: true,
showStack: true
}));
console.log("Server showing %s listening at http://%s:%s", publicDir, hostname, port);
app.listen(port);

Your form action is '', therefor the URL created by the form will be
/?name=xxx&code=yyy etc
From your routing, it seems like you're expecting the url to be in the form of /xxx?code=yyy.
Make your form action '/search' and add the following JS.
app.get("/search", function (req, res){
console.log("shubham batra");
var keyword = req.query.code;
console.log(keyword);
//res.send('You sent the name "' + req.query.name + '".');
});
As your making a get request, request.body won't be set.

You can use as multiple as you want like:
var code = req.query.code;
var category = req.query.category;
var brand = req.query.brand;
req.query if its GET request and req.body if its POST.

change the app.get("/index/:name", function (req, res){
to app.get("/index/:name?", function (req, res){
that your route will match /index/ and /index/anyname routes
and change form action to "/" or something like "/action"

Related

Redirect to another url after post request (AJAX, EXPRESS)

As a part of learning node.js servers I'm working on a little log-in website. There's a site you can open and enter your username which will then be sent through an ajax post request to the server and saved into an array of all users. I wanna make it so that after you submit your username, you will be redirected to another page, unique for every username, where you will be able to see the information about you username. Sort of a 'manage your account' site.
However, I can't seem to figure out a way to redirect me to this page after I have submitted an username.
Say for example you submit a username 'kokot' and it's the 3rd username that's been submitted so far. Thus, in the 'players' array, your user object will look something like this {id: 2, username: 'kokot'}.
Now I want to redirect you to the url localhost:2000/players/2 to see the info about your specific username.
NODE JS
const express = require('express');
const server = express();
const bodyParser = require('body-parser');
server.use(bodyParser.urlencoded({extended: false}));
server.use(bodyParser.json());
let players = [];
//loads the home page
server.get('/', (req, res) =>{
res.sendFile(__dirname + '/home.html');
});
//loads the page with the list of players
server.get('/players', (req, res) =>{
res.send(players);
});
server.get('/player/:id', (req, res) =>{
res.send(players[req.params.id]);
});
//takes a new username and saves it to players array
server.post('/', (req, res) =>{
console.log('NEW PLAYER: ' + req.body.username);
players.push({
id: players.length,
username: req.body.username
});
});
/////////////////////////////////////////////////////////////////////////////
server.listen(2000, () => console.log('LISTENING ON PORT 2000'));
HTML
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<title>Home</title>
</head>
<body>
<h1>PISKVOREC</h1>
<form id="userForm">
username
<input type="text" name="text" id="userFormInput">
<input type="submit" name="Submit" id="userFormSubmit">
</form>
<script>
$(document).ready(()=>{
let homeUrl = 'http://localhost:2000';
let $userForm = $('#userForm');
let $userFormSubmit = $('#userFormSubmit');
//submits a new username to the server
$userFormSubmit.click(() =>{
$.post(homeUrl, {
username: $('#userFormInput').val()
}, function(){
console.log('USERNAME SUBMITTED TO SERVER');
});
$.
});
////////////////////
});
</script>
</body>
</html>
Thank you for you responses and ideas
Have a nice day
Sure, see below:
server.post('/', (req, res) =>{
console.log('NEW PLAYER: ' + req.body.username);
players.push({
id: players.length,
username: req.body.username
});
res.redirect(`/player/${req.body.username}`);
});
UPDATE
Demo with vanilla Express.js app
app.js
var express = require('express');
var path = require('path');
var bodyParser = require('body-parser');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
app.use(bodyParser.urlencoded({extended: false}));
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
app.post('/this', (req, res, next) => {
res.redirect(`/that/${req.body.username}`);
});
app.get('/that/:id', (req, res, next) => {
res.send(req.params);
});
module.exports = app;
index.hbs
<form method="post" action="/this">
<input id="username" name="username" value="vader" type="text" />
<button type="submit">Submit</button>
</form>
results in a redirect to: http://localhost:3000/that/vader

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 });
});

NodeJS no response on submit

I have a local server running and an input form for users. I want when they press submit simply to output a message "Thank you!". Instead when pressing submit, nothing happens and after some time I get the message that the server dropped the connection. Could somebody help me please?
NodeJS:
var fs = require('fs');
const log=require('simple-node-logger').createSimpleLogger();
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
var port = process.env.PORT || 8000;
app.use(express.static(__dirname + '/server'));
app.use(express.static(__dirname + '/public'));
app.use('/images', express.static(__dirname +'/images'));
app.get('/', function(req, res){
res.sendfile('main.html');
});
//app.listen(port, function(){
// console.log('server is running on ' + port);
//});
app.post('/submit', function(req, res){
console.log(req.body.rank);
});
HTML:
<form method="POST" action="/submit" >
<img src="images/Picture1.png" style="width:280px;"/>
<br />
<select name="rank" size="1" style="width:80px;" required>
<option value="" selected disabled hidden>Rank</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
<br />
<input type="submit" value="Submit" name="submit" id="submit"/>
</form>
Your post handler does nothing
app.post('/submit', function(req, res){
console.log(req.body.rank);
});
You can do the following action,
Redirect on another route with res.redirect :
app.post('/submit', function(req, res){
console.log(req.body.rank);
// redirect on /
return res.redirect("/");
});
Render a success html file:
app.post('/submit', function(req, res){
console.log(req.body.rank);
// render success
return res.sendfile('success.html');
});
Return json :
app.post('/submit', function(req, res){
console.log(req.body.rank);
// render success
return res.status(200).json({message: "OK"})
});
Its happed because you in your post handler never produces any feedback to client, just log to console rank. Try something like
app.post('/submit', function(req, res){
console.log(req.body.rank);
res.json(req.body.rank);
});

Express.js routers post request returns 404

My express server returns 404 error when i try to send request from html form. However get request works fine. I have separated files for server and routes. I can't make requests in app.js, because there are too many of them (for different pages). I want to make post-insert request to db, but i just can't get any information from my form.
Is there something i missing?
my html form (ejs precisely)
<form action="/add" method="POST">
<input type="text" name="title" placeholder="Event name" />
<input type="text" name="subcategory" placeholder="Category" />
<input type="text" name="date" placeholder="Date" />
<input type="text" name="place" placeholder="Place" />
<input type="text" name="organisator" placeholder="Organisator" />
<textarea name="description" placeholder="Description" onkeyup="adjust_textarea(this)"></textarea>
<input type="submit" value="Add" />
</form>
my App.js file (error on 404 handler)
const express = require('express');
const path = require('path');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
//db connection
var mysql = require("mysql");
app.use(function(req, res, next){
res.locals.connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'mypassword',
database : 'mydb'
});
res.locals.connection.connect();
next();
});
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', require('./routes/index'));
app.use('/events', require('./routes/events'));
//handling errors
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
app.use(function(err, req, res, next) {
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
res.status(err.status || 500);
res.render('error');
});
//server init
var http = require('http');
var server = http.createServer(app);
server.listen(4000);
if(server.listening){
console.log('Server is listening on port 4000');
}
module.exports = app;
my ./routes/events.js file
const express = require('express');
const router = express.Router();
router.get('/', function (req, res, next) {
let query = '*select query*';
res.locals.connection.query(query, function (error, results, fields) {
if (error) throw error;
res.render('index', { title: 'Events', data: results });
});
});
router.post('/add', function (req, res) {
var obj = req.body.title;
console.log(obj);
res.redirect('/events');
});
What i see in browser
You have the 'add' endpoint listed in in your 'routes/events.js' file, which causes the structure of the final route to be '/events/add.' In your form, you are sending to the '/add' endpoint so to fix the issue, either change the action prop on the form to '/events/add' or move the '/add' endpoint into it's own route like this:
router.post('/add', function(req, res) {
var obj = req.body.title;
console.log(obj);
res.redirect('/events');
});

Cannot POST to a route from and HTML form

I'm building a nodejs/expressjs application and this is my architecture:
+ routes
- candidate.js
- index.js
+ views
- layout.vash
- register.vash
- server.js
in my server.js file, I put this code to manage routes:
var routes = require('./routes/index');
var candidate = require('./routes/candidate');
app.use('/', routes);
app.use('/candidate', candidate);
in candidate.js, all get requests work fine, but there is a problem in post requests, it can't resolve the path: Cannot POST /caregister
server.js
var routes = require('./routes/index');
var candidate = require('./routes/candidate');
var employer = require('./routes/employer');
var app = express();
app.set('view engine', 'vash');
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);
app.use('/candidate', candidate);
app.use('/employer', employer);
app.set('port', (process.env.PORT || 3000));
app.listen(app.get('port'), function(){
console.log('server is listening to ' + app.get('port'));
});
routes/index.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res){
res.render('index');
});
module.exports = router;
routes/candidate.js
var express = require('express');
var router = express.Router();
var Candidate = require("../models/candidate");
router.get('/', function(req, res){
res.render('candidatelogin'); // relative to candidatelogin.vash
});
router.post('/caregister', function(req, res){
var username = req.body.username;
var email = req.body.email;
var password = req.body.password;
var passwordConf = req.body.passwordConf;
console.log(username + " " + email);
});
module.exports = router;
views/candidatelogin.vash
#html.extend('layout', function(model){
#html.block('body', function(model){
<h1>Jobseeker</h>
<div id="register">
<h3>Create new Account</h3>
<form method="post" action="/caregister">
<input type="text" name="username" placeholder="username"><br/><br/>
<input type="text" name="email" placeholder="email"><br/><br/>
<input type="password" name="password" placeholder="password"><br/><br/>
<input type="password" name="passwordConf" placeholder="password confirmation"><br/><br/>
<input type="submit" value="Register">
</form>
</div>
})
})
When using app.use and including a prefix like candidate that means that you should use this prefix to access this route later on.
So your form in candidatelogin.vash should post to /candidate/caregister url:
<div id="register">
<h3>Create new Account</h3>
<form method="post" action="/candidate/caregister">
<input type="text" name="username" placeholder="username"><br/><br/>
<input type="text" name="email" placeholder="email"><br/><br/>
<input type="password" name="password" placeholder="password"><br/><br/>
<input type="password" name="passwordConf" placeholder="password confirmation"><br/><br/>
<input type="submit" value="Register">
</form>
</div>

Categories