Can't retrieve value from input field express pug - node.js

I'm confused as to why I can't properly retrieve the value I enter into the input field in the pug code below. I have similar sections in this file that are written pretty much exactly the same and they work fine but for whatever reason I cannot pull the title value from the input field when referencing it from my express code.
index.pug html code:
section(class="get")
h3 Get Data By Title
form(action="/get-data",method="get")
div(class="input")
label(for="title") Title
input(type="text", id="title", name="title")
button(type="submit") LOAD
div
if posts
each val in items
article(class="item")
div Title: #{val.title}
div Content: #{val.content}
div Author: #{val.author}
div ID: #{val._id}
And the express code in my index.js file where I try to retrieve the value from input with id="title" and use it to query my database:
router.get('/get-data', function(req, res, next) {
console.log("get-data")
var item = {
title: req.body.title
};
console.log(item);
// Use mongoose to find data from database
UserData.find(item)
.then(function(doc) {
console.log(doc)
res.render('index', {title:"Movie Database",items: doc});
}).catch(err => console.log(err));
});
When I view the console output I can see that I retrieve no value, despite the value I entered appearing in my get query url.
0|myapp_node | get-data
0|myapp_node | { title: undefined }
0|myapp_node | []
0|myapp_node | GET /get-data?title=findme 304 54.497 ms - -
0|myapp_node | GET /stylesheets/style.css 304 0.382 ms - -
Below is the entire rendered HTML from pug for my file. It includes extra information that may or may not be relevant:
<!DOCTYPE html>
<html>
<head>
<title>Movie Database</title>
<link rel="stylesheet" href="/stylesheets/style.css">
</head>
<body>
<h1>Movie Database</h1>
<p>Welcome to Movie Database</p>
<section class="insert">
<h3>Insert Data</h3>
<form action="/insert" method="post">
<div class="input">
<label for="title">Title</label>
<input type="text" id="title" name="title">
</div>
<div class="input">
<label for="content">Content</label>
<input type="text" id="content" name="content">
</div>
<div class="input">
<label for="author">Author</label>
<input type="text" id="author" name="author">
</div>
<button type="submit">INSERT</button>
</form>
</section>
<section class="get">
<h3>Get Data By Title</h3>
<form action="/get-data" method="get">
<div class="input">
<label for="title">Title</label>
<input type="text" id="title" name="title">
</div>
<button type="submit">LOAD</button>
</form>
<div></div>
</section>
<section class="update">
<h3>Update Data</h3>
<form action="/update" method="post">
<div class="input">
<label for="title">Title</label>
<input type="text" id="title" name="title">
</div>
<div class="input">
<label for="id">ID</label>
<input type="text" id="id" name="id">
</div>
<div class="input">
<label for="content">Content</label>
<input type="text" id="content" name="content">
</div>
<div class="input">
<label for="author">Author</label>
<input type="text" id="author" name="author">
</div>
<button type="submit">UPDATE</button>
</form>
</section>
</body>
</html>
And here is my app.js file:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
// var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
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;

So the data you're looking for is on the query property of your request object. The way that you know this is that, in your server log, you see:
GET /get-data?title=findme
When you see a ? following the path, there's a query coming through on the request object. To access those properties, you just tap into req.query.title or req.query.you_prop_name_here.
Here's a snippet from the express docs to show you how this works a bit more.
// GET /search?q=tobi+ferret
req.query.q
// => "tobi ferret"
// GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse
req.query.order
// => "desc"
req.query.shoe.color
// => "blue"
req.query.shoe.type
// => "converse"

Related

I can't retrieve req.body data with multer

I can't retrieve the data from req.body using multer. It responds with
[Object: null prototype] {} , if I stringify it as JSON I ofc get {}
My goal is to receive input number in order to add X amount of product to the cart, but I can't seem to get the number.
{{# each products }}
<div class="row">
{{# each this }}
<div class="col-sm-6 col-md-4">
<form action = "/add-to-cart/{{this._id}}" method="post" enctype="multipart/form-data">
<div class="img-thumbnail" alt="text-center">
<div class="thumbnail">
<img src="{{this.imagePath}}" class="img-fluid" alt="Responsive image">
<div class="caption">
<h3>{{this.title}}</h3>
<p class="description">{{this.description}}</p>
<div class="clearfix">
<input type="text" name="Quantity" placeholder="vnt" form="insert-id-of-form" class="float-left">
<div class="price float-left">{{this.price}}</div>
<input type="submit" class="fadeIn fourth" value="Užsakyti">
</div>
</div>
</div>
</div>
</div>
</form>
{{/each}}
</div>
{{/each}}
This is my code in.js
router.post('/add-to-cart/:id',upload.single("Quantity"), function(req, res, next) {
var productId = req.params.id;
var cart = new Cart(req.session.cart ? req.session.cart : {});
Product.findById(productId, function(err, product) {
var boxSize = req.session.boxSize;
const itemQty = req.body;
console.log(itemQty);
if (err) {
return res.redirect('/products');
}
else if (cart.boxSizeQty < boxSize && itemQty == null){
cart.add(product, product.id);
req.session.cart = cart;
res.redirect('/products');
console.log("item qty null")
}
else if (cart.boxSizeQty >= boxSize && itemQty > boxSize){
res.redirect('/products');
req.flash('error','Dėžutė pilna');
console.log("more items than size")
}
else if (cart.boxSizeQty < boxSize && itemQty > 0){
console.log("item quantity is more than 0")
for (var i = 0; i <= itemQty; i++){
cart.add(product, product.id);
}
req.session.cart = cart;
res.redirect('/products');
}
});
});
This is part of the app.sj
var indexRouter = require('./routes/index');
var userRouter = require('./routes/user');
var app = express();
var bodyParser = require('body-parser')
var multer = require('multer');
var forms = multer();
mongoose.connect('mongodb://localhost:27017/shopping', {useNewUrlParser: true, useUnifiedTopology: true});
require('./config/passport');
// view engine setup
app.use(bodyParser.json());
app.use(forms.array());
app.use(bodyParser.urlencoded({ extended: true }));
app.engine('.hbs', expressHbs({defaultLayout: 'layout', extname: '.hbs'}));
app.set('view engine', '.hbs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(validator());
app.use(cookieParser());
I've tried this with multer, formidable, bodyparser but it doesn't seem to parse the input number. Very much stuck on this. Any help would be appreciated.
Kind regards,
Just posting the answer here, if anyone will get in to a similar issue.
Apparently the problem was that for data wasn't being passed though nodejs part was working fine. It's my mistake for not going to developer options on browser and checking form data which was empty.
Once html part is in one div
{{# each products }}
<div class="row form-group">
{{# each this }}
<form action = "/add-to-cart/{{this._id}}" method="post" enctype="multipart/form-data">
<div class="form-group">
<img src="{{this.imagePath}}" class="img-fluid" alt="Responsive image">
<h3>{{this.title}}</h3>
<p class="description">{{this.description}}</p>
<input type="number" name="Quantity" placeholder="vnt" class="float-left">
<input type="submit" class="fadeIn fourth" value="Užsakyti">
</div>
</form>
{{/each}}
</div>
{{/each}}
The data is being properly passed from this form.
Then we need to stringify it to JSON like so:
var itemQty = JSON.parse(JSON.stringify(req.body.Quantity));
And parse it as int like so:
parseInt(itemQty);
All is left is to fix the view.
Thanks to anyone who bothered to read.

Modal box on the node js

I have the file upload api, which send out the SUCCESS message on the file upload and the FAILURE message when the file not selected.
app.js
const express = require("express");
const app = express();
const http = require("http").Server(app).listen(3000);
const upload = require("express-fileupload");
const request = require("request");
app.use(express.urlencoded());
app.use(express.json());
app.use(upload({
useTempFiles: true,
tempFileDir: '/tmp/'
}));
console.log("Server Started");
// To load both HTML and CSS files on the root call
app.use(express.static(__dirname + "/public"));
app.get("/", function (req, res) {
res.sendFile(__dirname + "/index.html");
}
)
app.post("/", function (req, res) {
if (req.files.filename.name) {
res.send("uploaded");
}
else
res.send("Please select the file to upload!");
})
Instead res.send(), i want to display some modal box defined on my html code. Need a help on how to incorporate or shown this modal box upon my post request.
index.html
<link rel="stylesheet" href="index.css">
<div class="hdngTab">
<h1 style="align-content: center"> Utility</h1>
</div>
<div class="test">
<form label="upload" method="post" enctype="multipart/form-data" action="/">
<div class="sf-ref">
<label> Ticket Reference </label>
<input type="text" name="sftext"> </input>
</div>
<br><br>
<input style="font-size: 20px; padding-left: 180px" type="file" name="filename">
<!--input style="font-size: 20px" type="submit" value="Upload"-->
<button class="trigger" style="font-size: 20px" value="Upload">
Upload </button>
</form>
</div>
<div class="modal">
<div class="modal-content">
<span class="close-button">×</span>
<h1>Hello, I am a modal!</h1>
</div>
</div>

How to use an Angular app as your View Engine with Node.js

I am trying to create an Angular app that sends an email using Nodemailer.
I am able to create a standard Angular app that contains a form. I then want to pass data from this form to a .JS file which will then use Nodemailer to send that data to an email address.
All the examples I have found so far for Nodemailer use View engines such as handlebars, etc. but I want to use my angular app's HTML rather than a view engine.
How do I pass data from my Angular app's form to a .JS file to send an email without having to use a View Engine?
Below is what I have so far in my Angular app:
<form method="POST" action="send">
<p>
<label>Name</label>
<input type="text" name="name">
</p>
<p>
<label>Company</label>
<input type="text" name="company">
</p>
<p>
<label>Email Address</label>
<input type="email" name="email">
</p>
<p>
<label>Phone Number</label>
<input type="text" name="phone">
</p>
<p class="full">
<label>Message</label>
<textarea name="message" rows="5"></textarea>
</p>
<p class="full">
<button type="submit">Submit</button>
</p>
</form>
And this is what I have in the tutorial code:
APP.JS
const express = require("express");
const bodyParser = require("body-parser");
const exphbs = require("express-handlebars");
const path = require("path");
const nodemailer = require("nodemailer");
const app = express();
// View engine setup
app.engine("handlebars", exphbs());
app.set("view engine", "handlebars");
// Static folder
app.use("/public", express.static(path.join(__dirname, "public")));
// Body Parser Middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.get("/", (req, res) => {
res.render("contact");
});
app.post("/send", async (req, res) => {
const output = `
<p>You have a new contact request</p>
<h3>Contact Details</h3>
<ul>
<li>Name: ${req.body.name}</li>
<li>Company: ${req.body.company}</li>
<li>Email: ${req.body.email}</li>
<li>Phone: ${req.body.phone}</li>
</ul>
<h3>Message</h3>
<p>${req.body.message}</p>
`;
try{
var transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: "myemail#mail.com",
pass: "myPassword"
},
tls: {
rejectUnauthorized: false
}
});
}
catch(err){
console.log(err.message);
}
const mailOptions = {
from: "myemail#mail.com", // sender address
to: "myemail#mail.com", // list of receivers
subject: "Test email", // Subject line
html: output // plain text body
};
let info = await transporter.sendMail(mailOptions);
console.log("Message sent: %s", info.messageId);
console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
res.render("contact", { msg: "Email has been sent" });
});
app.listen(3000, () => console.log("Server started..."));
CONTACT.HANDLEBARS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Acme Web Design</title>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"
integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.css" />
<link rel="stylesheet" href="public/css/style.css">
</head>
<body>
<div class="container">
<h1 class="brand"><span>Acme</span> Web Design</h1>
<div class="wrapper animated bounceInLeft">
<div class="company-info">
<h3>Acme Web Design</h3>
<ul>
<li><i class="fa fa-road"></i> 44 Something st</li>
<li><i class="fa fa-phone"></i> (555) 555-5555</li>
<li><i class="fa fa-envelope"></i> test#acme.test</li>
</ul>
</div>
<div class="contact">
<h3>Email Us</h3>
{{ msg }}
<form method="POST" action="send">
<p>
<label>Name</label>
<input type="text" name="name">
</p>
<p>
<label>Company</label>
<input type="text" name="company">
</p>
<p>
<label>Email Address</label>
<input type="email" name="email">
</p>
<p>
<label>Phone Number</label>
<input type="text" name="phone">
</p>
<p class="full">
<label>Message</label>
<textarea name="message" rows="5"></textarea>
</p>
<p class="full">
<button type="submit">Submit</button>
</p>
</form>
</div>
</div>
</div>
</body>
I can post further code if necessary.
So I managed to pass data from the form (root.component.html) to the server (app.js), capture it & print it to the console via the POST method.
Code is below:
root.component.html:
<form #emailForm="ngForm">
<div class="col-md-6">
<div>
<label for="username">
Username
</label>
<input
type="text"
id="username"
[(ngModel)]="username"
required
name="username"
#txtUsername="ngModel"
/>
</div>
<div>
<label for="message">Message</label>
<textarea
id="message"
placeholder="Please enter your message here"
[(ngModel)]="message"
required
name="message"
#txtMessage="ngModel"
></textarea>
</div>
<button
axis-button
class="axis-btn"
title="Submit"
data-kind="primary"
(click)="sendMessage()"
[disabled]="emailForm.invalid"
>
Send Email
</button>
</div>
</form>
root.component.ts:
export class RootComponent implements OnInit {
constructor(private rootService: RootService) {}
username: string;
message: string;
ngOnInit() {
this.getData();
}
getData() {
this.rootService.getAPIData().subscribe(
response => {
console.log('response from GET API is ', response);
},
error => {
console.log('error is ', error);
}
);
}
postData(name: string, message: string) {
this.rootService.postAPIData(name, message).subscribe(
response => {
console.log('response from POST API is ', response);
},
error => {
console.log('error during post is ', error);
}
);
}
sendMessage() {
this.postData(this.username, this.message);
}
}
root.service.ts:
export class RootService {
constructor(private http: HttpClient) {}
getAPIData() {
return this.http.get('https://jsonplaceholder.typicode.com/users');
}
postAPIData(name: string, message: string) {
return this.http.post('/api/postData', {
name: name,
message: message
});
}
}
app.js:
const express = require('express')
const app = express()
const bodyParser = require('body-parser')
app.get('/', (req, res) => {
res.send('Welcome to Node API')
})
app.get('/getData', (req, res) => {
res.json({'message': 'Hello World'})
})
app.post('/postData', bodyParser.json(), (req, res) => {
res.json(req.body) // Prints the request body to the browser console
const output = `Name: ${req.body.name}......Email: ${req.body.message}`;
console.log(output);
})
app.listen(3000, () => console.log('Example app listening on port 3000!'))

Node.js/Express post request unsuccessful

I have a simple CRUD app in Node.js/Express. It's an order intake form to post data to a MongoDB collection.
I cannot for the life of me see why this POST (CREATE) route is not succeeding. I’ve been troubleshooting this all morning. My other routes run just fine as validated with my console.logs.
Here is my orders route file (/routes/orders.js):
var express = require("express");
var router = express.Router();
var Order = require("../models/order.js");
// Load Keys ===================================================================
const keys = require('../config/keys');
// INDEX ROUTE - show all orders
router.get("/", isLoggedIn, function(req, res){
// Get all orders from DB
Order.find({}, function(err, allOrders){
if(err){
console.log(err);
} else {
res.render("orders", {orders:allOrders});
//Test to see if this returns the number of records in the collection
console.log("There are currently " + allOrders.length + " orders.");
}
});
});
// CREATE ROUTE - add new order to the DB
router.post("/", isLoggedIn, function(req, res){
// get data from form and add to newOrder object
var date = req.body.date;
var territory = req.body.territory;
var principal = req.body.principal;
var customer = req.body.customer;
var representative = req.body.representative;
var amount = req.body.amount;
var newOrder = {date: date, territory: territory, principal: principal, customer: customer, representative: representative, amount: amount};
// Create a new order and save to DB
Order.create(newOrder, function (err, newlyCreated){
if(err){
console.log(err);
} else {
//redirect back to orders page
res.redirect("/");
console.log("New order created (orders route file).");
}
});
});
// NEW ROUTE - show form to create new customer
router.get("/new", isLoggedIn, function(req, res){
res.render("new.ejs");
console.log("This is coming from the order route js file.");
});
This is my new.ejs template file with the form:
<div class="container container-new py-5">
<div class = "row">
<div class="col-lg-12 orders-title">
<h2>New Order</h2>
</div>
</div>
<div class="row">
<div class="col-md-10 mx-auto">
<form action="/orders" method="POST">
<div class="form-group row">
<div class="col-sm-3">
<label for="inputDate">Date</label>
<input type="text" class="form-control" id='datetimepicker' name="date">
</div>
<div class="col-sm-3">
<label for="inputTerritory">Territory</label>
<select id="selectTerr" class="form-control" name="territory">
<option>Choose a territory</option>
</select>
</div>
<div class="col-sm-6">
<label for="inputPrincipal">Principal</label>
<select id="selectPrin" class="form-control" name="principal">
<option>Choose a principal</option>
</select>
</div>
</div>
<div class="form-group row">
<div class="col-sm-5">
<label for="inputCustomer">Customer</label>
<select id="selectCust" class="form-control" name="customer">
<option>Choose a customer</option>
</select>
</div>
<div class="col-sm-4">
<label for="inputRepresentative">Sales Rep</label>
<select id="selectRep" class="form-control" name="representative">
<option>Choose a rep</option>
</select>
</div>
<div class="col-sm-3">
<label for="inputState">Total</label>
<input type="text" class="form-control" id="inputTotal" name="amount">
</div>
</div>
<div class="form-group new-buttons">
<button type="button" class="btn btn-cancel btn-default btn-primary px-4">Clear</button>
<button type="button" class="btn btn-submit btn-default btn-primary px-4">Submit</button>
</div>
</form>
</div>
</div>
<div class = "row row-back">
<div class="col-lg-12 orders-title">
Back to Main
</div>
</div>
</div>
app.js:
var express = require("express"),
app = express(),
bodyParser = require("body-parser"),
mongoose = require("mongoose"),
passport = require("passport"),
LocalStrategy = require("passport-local"),
passportLocalMongoose = require("passport-local-mongoose"),
methodOverride = require("method-override"),
seedDB = require("./seeds");
// seedDB();
// Requiring Routes ============================================================
var ordersRoutes = require("./routes/orders"),
indexRoutes = require("./routes/index");
// Load Keys ===================================================================
const keys = require('./config/keys');
// Map global promises
mongoose.Promise = global.Promise;
// Mongoose Connect ============================================================
mongoose.connect(keys.mongoURI, {
useMongoClient: true
})
.then(() => console.log('MongoDB Connected'))
.catch(err => console.log(err));
//==============================================================================
app.use(express.static('public'));
app.use(bodyParser.urlencoded({extended: true}));
app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');
app.use(methodOverride("_method"));
app.use(indexRoutes);
app.use("/orders", ordersRoutes);
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`server started on port ${port}`));

How to use a form to send values to JS file and execute NodeJS

I'm starting in NodeJS and to practice I'm creating a project where I have a form with some fields, the form is created inside the views folder as teste.ejs.
Teste.ejs
<div class="container">
<form id="form1" method="POST" action="/inndetails.js">
<div class="row">
<div class="col-25">
<label for="fname">MerchantID</label>
</div>
<div class="col-75">
<input type="text" id="fname" name="merchantid" placeholder="MerchantID..">
</div>
<div class="row"><div class="row">
<div class="col-25">
<label for="fname">Valor</label>
</div>
<div class="col-75">
<input type="text" id="valor" name="valor" placeholder="Valor..">
</div>
<div class="row">
<input type="submit" value="Submit">
</div>
This form has two fields "MerchantID" and "Valor". I want when I submit using POST the values from these fields go to an JS file called "inndetails.js" and execute this file.
Inndetails.js
sdk.getIinDetails({
'psp_Version': '2.2',
'psp_MerchantId': '**From the form**',
'psp_IIN': '**From the form**',
'psp_PosDateTime': '2016-12-01 12:00:00'
},
function (error, response) {
if (error) {
console.log(error)
} else {
console.log(response);
}
});
I am already using Express and Body Parser, In my routes folder I have the file index.js contains:
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var router = express.Router();
router.post('/teste2', urlencodeParser, function(req, res) {
console.log(req.body);
res.render('teste2', ´{data: req.body});
});
I can get the values from the form and show in another page for example in teste2.ejs, using:
<p>MerchantID: <%= data.merchantid %></p>
<p>Valor: <% data.valor %></p>
I think you need to change your index.js file to
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var router = express.Router();
router.post('/teste2', bodyParser.urlencoded({limit: '50mb', extended: false }), function(req, res) {
console.log(req.body);
res.render('teste2', ´{data: req.body});
});
The parameters {limit: '50mb', extended: false } is an option, and you can see the others here https://www.npmjs.com/package/body-parser
`

Resources