Retrieve post parameter to send - javascript

First, Sorry if I got the title wrong, I am new and dunno how to start and the terms,
what I want to do is
<form action="/" method="POST">
<select name="cash" id="first">
<option value="AED">AED</option>...
get the value of 'cash' i.e AED
app.post("/", function(.............) {
request(..............)
var cash = req.body.cash;
console.log(cash);
var data = JSON.parse(body);
var price = data.rates.cash;
console.log(price);
res.send( price);}
make a post request and make api call select the price(AED) and res.send and "How to retrieve POST query parameters?" this didn't help me.
const express = require('express');
const app = express();
var bodyParser = require('body-parser');
const request = require('request');
app.use(express.json());
app.use(bodyParser.urlencoded({
extended: true
}));

You can do something like this.
<form method="post" action="http://127.0.0.1:8080/">
<select name="cash" id="first">
<option value="AED">AED</option>
<input type="submit" value="Submit">
</form>
Enter full URL like
<form action="http://127.0.0.1:8080/" method="post">
Node js
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
//Note that in version 4 of express, express.bodyParser() was
//deprecated in favor of a separate 'body-parser' module.
app.use(bodyParser.urlencoded({ extended: true }));
//app.use(express.bodyParser());
// access your body data here
app.post('/', function(req, res) {
res.send('You sent the code "' + req.body.cash + '".');
});
app.listen(8080, function() {
console.log('Server running at http://127.0.0.1:8080/');
});

As I understand correctly you want to:
POST form data to backend
during data processing, request 3rd party API for a price
return a price to the user
The form view index.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<form action="/" method="POST">
<select name="cash" id="first">
<option value="AED">AED</option>
<option value="USD">USD</option>
</select>
<button id="submit" type="submit">Submit</button>
</form>
<% if (cash && price) { %>
<p>The price for <%= cash %> is <%= price %>.</p>
<% } %>
</body>
</html>
I'm using EJS to conditionally display the price below the <form>.
Here is Express backend:
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
// I advise you to use axios instead of request for convenience
const axios = require('axios');
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', 'ejs');
app.get('/', function (req, res) {
if (req.query.cash && req.query.price) {
res.render('index', { cash: req.query.cash, price: req.query.price });
}
res.render('index', { cash: null, price: null });
});
app.post('/', async function (req, res) {
const cash = req.body.cash;
try {
const response = await axios.post(
'paste_your_url', { cash }
);
res.redirect(`/?cash=${cash}&price=${response.data.price}`);
} catch (err) {
console.log(err);
}
});
app.listen(3000);
When the user enters the page /, Express renders index.ejs view without price information.
When the user submits the form to backend, Express:
reads the data,
requests 3rd party API,
reads the price from 3rd party response,
redirects user back to / with values in query string ?cash=<value>&price=<value>. This let Express render index.ejs with price information.
Also, I used axios instead of request, because it makes code more readable and easier (due to async/await).

Related

Why does req.body return an empty object in console in POST request?

In my code below, the middleware is supposed to return the parsed data in console as an object accessed by req.body, but it returns an empty object for some reason.
Code and Console Snapshot1
Code and Console Snapshot2
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
const { use } = require('express/lib/application');
/*
ulrEncodedParser middleware is used to invoke below function
to parse posted data to POST functions
var urlEncodedParser = bodyParser.urlencoded({extended : false});
var jsonParser = bodyParser.json();
*/
//set view engine to be able to visit views
app.set('view engine', 'ejs');
//middleware for styles to be loaded on pages when req made by views
app.use('/stylesheets', express.static('stylesheets'));
// middleware to parse application/x-www-form-urlencoded
//app.use(bodyParser.urlencoded({ extended: false }));
// middleware to parse application/json
//app.use(bodyParser.json());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
//GET "/" req, fires up home page
app.get('/', function(req, res){
res.render('home');
});
//GET "/home" req, aslo fires up home page
app.get('/home', function(req, res){
res.render('home');
});
//GET "/signup" req, fires up sign up page
app.get('/signup', function(req, res){
res.render('signup');
});
//POST information enetered on sign up form
app.post('/signup', function(req, res){
console.log(req.body);
//res.render('signup-success', req.body);
});
//server to run on port 3000
app.listen(3000, function(){
console.log('server listening on port 3000');
});
I also tried initialize two separate variables where the functions of urlencoded() and bodyParser.json() can be accessed var for both middlewares instead of using app.use() middleware this way:
var urlEncodedParser = bodyParser.urlencoded({extended : false});
var jsonParser = bodyParser.json();
and then pass in each in the app.post() request routed to the signup page but it still returns the same, empty.
Here is my signup.ejs as well for reference.
<!DOCTYPE html>
<html>
<head>
<link href="/stylesheets/style.css" rel="stylesheet" type="text/css" />
<title>Sign Up Page</title>
</head>
<body>
<h1>Sign Up</h1>
<h3>Enter the requested information below for your user profile to be created.</h3><br>
<form id="signup-form" action="/signup" method="post">
<label for="firstName">First Name</label><br>
<input type="text" id="firstName" placeholder="first name"><br><br>
<label for="musicPreferences">Music Prefrences</label><br>
<input type="text" id="musicPrefrence" placeholder="music preferences"><br><br>
<label for="favoriteArtists">Favorite Artists</label<br>
<input type="text" id="favoriteArtists" placeholder="favorite artists"><br><br>
<label for="pastConcerts">Past Concerts Attended</label><br>
<input type="text" id="pastConcerts" placeholder="concerts attended"><br><br>
<label for="futureConcerts">Fututre Concerts Want to Attend</label><br>
<input type="text" id="futureConcerts" placeholder="future concerts"><br><br>
<input type="submit" value="submit"><br>
<%- include('partials/nav.ejs') %>
</form>
</body>
</html>
Sign up Page UI
Any help is appreciated!
The backend works correctly because when sending a request with curl, body is shown in the console. It seems the client sends the request incorrectly.
screenshot

Javascript / EJS Code showing error : TypeError: Cannot read properties of null (reading 'name')

The code does run at first but the moment I submit my first post request, it gives the following error :
node:events:504
throw er; // Unhandled 'error' event
^
TypeError: Cannot read properties of null (reading 'name')
Currently using : Node.js, mongoose
Packages used : express, bodyParser, ejs, Mongoose
JS file code :
const express = require("express");
const app = express();
app.use(express.static("public"));
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({extended: true}));
const ejs = require("ejs");
app.set("view engine", "ejs");
const mongoose = require('mongoose');
mongoose.connect("mongodb://localhost:27017/learndb");
const questionSchema =
{
question : String,
answer : String
};
const Question = mongoose.model("Question", questionSchema);
const subjectSchema =
{
name : String,
questions : [questionSchema]
};
const Subject = mongoose.model("Subject", subjectSchema);
app.post("/", function(req, res)
{
const subjectName= req.body.subjectName;
const subject = new Subject({ name: subjectName});
subject.save();
res.redirect("/");
});
app.get("/", function(req, res)
{
Subject.find({}, function(err, foundSubjects)
{
res.render("home", {whichSubjects: foundSubjects});
});
});
HTML/EJS File code:
<body>
<h1>Choose a Subject</h1>
<% whichSubjects.forEach(function(eachSubject) { %>
<div class="">
<form class="" action="/<%=eachSubject.name%>" method="get">
<button type="submit" name="button"> <%=eachSubject.name%></button>
</form>
</div>
<% }) %>
<div class="">
<form class="" action="/" method="post">
<input type="text" name="subjectName" value="">
<button type="submit" name="button">Add A Subject</button>
</form>
</div>
</body>
The answer was so simple but we missed it. The first thing wrong in your code are the paths. You have two paths named /. You want to make your home route the place your visualize all the data and then make a form that posts the data to a different route and upon success, should redirect to your home route. In your case all you have to do is change the post route on the hmtl to /addsubject and on the js file to app.post('/addsubject' rest of code
//Generate express app
const express = require('express');
const app = express();
app.set('views', './views');
app.set('view engine', 'ejs');
//Generate body parser
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
//Connect to MongoDB
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/learndb');
const subJectSchema = new mongoose.Schema({
name: String,
questions: [{type: String}]
})
const Subject = mongoose.model('Subject', subJectSchema);
app.post('/addsubject', (req, res) => {
const subjectName = req.body.subjectName;
const subject = new Subject({ name: subjectName });
subject.save((err, subject) => {
if (err) {
console.log(err);
} else {
console.log("User Saved");
}
});
res.redirect('/');
});
app.get('/', (req, res) => {
Subject.find({}, (err, subjects) => {
if (err) {
console.log(err);
} else {
res.render('home', { subjectList: subjects });
}
});
});
app.listen(4000, () => {
console.log('Server started on port 3000');
});
<body>
<h1>Choose Subject</h1>
<div>
<form action="/addsubject" method="post">
<label for="name">Name</label>
<input type="text" name="subjectName" id="name">
<input type="submit" value="Create Subject">
</form>
</div>
<% if(subjectList.length> 0){ %>
<% subjectList.forEach(subject=>{ %>
<p>
<%= subject.name %>
</p>
<% }) %>
<% } else { %>
<p>No subjects found Add Some</p>
<% } %>
</body>

Cannot read property 'task' of undefined

enter image description hereI never faced this problem before but now "req.body.task" is not working and I don't know why its happening.
Here's the form
<form action="/" method="POST">
<div class="input-box">
<input type="text" name="task" id="" class="input-add">
<button type="submit" name="button" class="btn-add">+</button>
</div>
</form>
Here's the post request
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const app = express();
app.set(bodyParser.urlencoded({extended: false}));
app.use(express.static("public"));
let items = [];
app.get("/", (req,res) => {
res.sendFile(__dirname + "/index.html");
});
app.post("/", (req,res) => {
const item = req.body.task;
console.log(item);
});
app.listen(3000, () => {
console.log("Server running at port 3000");
});
This
app.set(bodyParser.urlencoded({extended: false}));
should be
app.use(bodyParser.urlencoded({extended: false}));
BodyParser is a middleware and should be used using app.use methods.
See the docs for more details
app.set is used to set values to app variables, for example view engines

NodeJS and MongoDB "Cannot POST /"

Been using mongoDB with the mongoose ODM and I can't seem to figure it out. I've been following a tutorial online, but when I test out my code, it gets redirected to an empty page that says "Cannot POST /"
Here is my code:
server.js
var mongoose = require("mongoose");
var bodyParser = require("body-parser");
var express = require("express");
var app = express();
var PORT = 3332;
app.use("/", express.static(__dirname));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
mongoose.Promise = global.Promise;
mongoose.connect("mongodb://localhost/gamedata", {
useNewUrlParser: true
});
var gameSchema = new mongoose.Schema({
nickname: String
});
var User = mongoose.model("User", gameSchema);
app.post("/addname", (req, res) =>{
var playerNickname = new User(req.body);
playerNickname.save()
.then(item => {
console.log("nickname created")
res.send("item saved to database");
})
.catch(err => {
res.status(400).send("unable to save to database");
console.log("error baby!");
});
});
app.listen(PORT, function () {
console.log("server is up and running using port " + PORT)
});
index.html
<html>
<link href="https://fonts.googleapis.com/css?family=Press+Start+2P&display=swap" rel="stylesheet">
<body>
<h1 class="center-align">Create Nickname</h1>
<form method="post" name="/addname">
<input id="pickName" type='text' name='pickName' placeholder='Nickname' required>
<input id='ready' value=" Ready >" type='submit'>
</form>
</body>
<script>
</script>
</html>
What seems to fix it is when i change
app.use("/", express.static(__dirname));
to the following code:
app.use("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
But in my specific case i cannot do this.
Does anyone know of a work around?
You should change your index.html
Insteady of use:
<form method="post" name="/addname">
you should use:
<form method="post" action="/addname">
This should solve your problem.
The Action Attribute
The action attribute defines the action to be performed when the form is submitted.
Usually, the form data is sent to a page on the server when the user clicks on the submit button.
In the example above, the form data is sent to a page on the server called "/addname". This page contains a script that handles the form data:
If the action attribute is omitted, the action is set to the current page.
The attribute "name" is used in input fields, not in the tag.
I just found some information here.
https://www.w3schools.com/html/html_forms.asp

How to use route path in express?

I stuck in figuring out how client file find routes function in express. My app structure is like that,
|-root
|--public
|---files
|---scripts
|---css
|--views
...
The client side html is as blow, which is in /public/files. It can be rendered to http://localhost:3000/files/like_animal.html correctly.
<html>
<body>
<form action="/handleForm" method="post">
name: <input name="usename"><br>
I like <input name="animal"><br>
<input type="submit" value="Go">
</form>
</body>
</html>
The js file is like that,
var express = require('express');
var app = express();
var path = require('path');
app.use(express.static(path.join(__dirname + 'public')));
console.log('start');
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use('/handleForm', (req, res) => {
var name = req.body.name;
var animal = req.body.animal;
console.log(name + " " + animal);
res.send('Thank you');
});
app.listen(3000, () => {
console.log('Listening on port 3000');
});
Now I am not sure where I should put this js file in. I tried to put it in /public/scripts or root, even also in /public/files. But nothing works. Every time I submit the form, the browser always show Cannot POST /handleForm. As a one-week newbie in express, I am totally lost. Any hint will be appreciated. Thanks a lot.
You should put your script at the root then specify the public's path like this.
app.use(express.static(path.join(__dirname, 'public')));
Another note, app.use is used to make a middleware. You should define your route using app.post.
app.post('/handleForm', (req, res) => {
// ...
});

Categories

Resources