Node.js/Express post request unsuccessful - node.js

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

Related

req.body.fname notworking in express it shows result as undefined

code
I am not sure why the below does not work .I tried to add app.use(express.json()); in index.js but still not working. Any idea on how to solve this?
when I console.log it shows undefined
I am trying to console log the data that is submitted in the html
var express = require('express');
var bodyParser = require('body-parser');
var request = require('request');
const { path } = require('express/lib/application');
var app = express();
app.use(bodyParser.urlencoded({ extended: true }))
app.use(express.static('public'))
app.get('/', function (req, res) {
res.sendFile(__dirname + "/Signup.html")
})
app.post('/Signup.html', function (req, res) {
var fname = req.body.fname
var lname = req.body.lastname
var email = req.body.email
console.log(fname, lname, email)
})
app.listen(3000, function () {
console.log("Running in 3000 ")
})
HTML
this is the html code
<form action="/Signup.html" method="post" >
<img class="mb-4" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcST1ViA_OmDA31rfd8ooDSmjLUeuh-HujXTwA&usqp=CAU" alt="" width="72" height="57">
<h1 class="h3 mb-3 fw-normal">Please sign in</h1>
<div class="form-floating top">
<input type="text" name="fname" id="fname" class="form-control top" placeholder="First Name" required>
<label for="floatingInput">First Name</label>
</div>
<div class="form-floating middle">
<input type="text" class="form-control middle" name="lastname" placeholder="Last Name">
<label for="floatingPassword">Last Name</label>
</div>
<div class="form-floating bottom">
<input type="email" class="form-control bottom" name="email" placeholder="email">
<label for="floatingPassword">Email</label>
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit">Sign Me Up</button>
<p class="mt-5 mb-3 text-muted">© The App Brewery</p>
</form>

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.

Insert form data from nodejs to mongodb

const express = require("express");
const handlebars = require("express-handlebars");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const path = require("path");
const app = express();
const port = 3000;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.engine(".hbs", handlebars({ defaultLayout: "main", extname: ".hbs" }));
app.set("view engine", ".hbs");
app.use(express.static(path.join(__dirname, "public")));
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
mongoose.Promise = global.Promise;
mongoose.connect(
"mongodb://usresa:passcode#mongodb-rukshi-shard-00-00.nerbj.gcp.mongodb.net:27017,mongodb-rukshi-shard-00-01.nerbj.gcp.mongodb.net:27017,mongodb-rukshi-shard-00-02.nerbj.gcp.mongodb.net:27017/db_name?ssl=true&replicaSet=atlas-dxrzem-shard-0&authSource=admin&retryWrites=true&w=majority",
{ useNewUrlParser: true, useUnifiedTopology: true }
);
const nameSchema = new mongoose.Schema({
name: String,
naquantityme: String,
description: String,
});
const User = mongoose.model("User", nameSchema);
app.get("/", (req, res) => {
res.render("login", { layout: "loginlayout" });
});
app.get("/home", (req, res) => {
res.render("dashboard", { layout: "main" });
});
app.use("/AddProduct", (req, res) => {
res.render("AddProduct", { layout: "main" });
});
app.post("/addproductform", (req, res) => {
var myData = new User(req.body);
myData
.save()
.then((item) => {
res.send("Product saved to database");
})
.catch((err) => {`enter code here`
res.status(400).send("Unable to save to database");
});`enter code here
});
app.listen(port, () => {
console.log("Server listening on port " + port);
});
///// Front End
<form id="form_validation" method="post" action="/addproductform">
<div class="form-group form-float">
<input type="text" class="form-control" placeholder="Product Name" name="name"
required>
</div>
<div class="form-group form-float">
<input type="text" class="form-control" placeholder="Quantity" name="quantity"
required>
</div>
{{!-- <div class="form-group">
<div class="radio inlineblock m-r-20">
<input type="radio" name="gender" id="male" class="with-gap" value="option1">
<label for="male">Male</label>
</div>
<div class="radio inlineblock">
<input type="radio" name="gender" id="Female" class="with-gap" value="option2"
checked="">
<label for="Female">Female</label>
</div>
</div> --}}
<div class="form-group form-float">
<textarea name="description" cols="30" rows="5" placeholder="Description"
class="form-control no-resize" required></textarea>
</div>
{{!-- <div class="form-group">
<div class="checkbox">
<input id="checkbox" type="checkbox">
<label for="checkbox">I have read and accept the terms</label>
</div>
</div> --}}
<button class="btn btn-raised btn-primary waves-effect" id="submitDetails"
name="submitDetails" type="submit">SUBMIT</button>
</form>
This is appjs code. Rest I have AddProduct in views folder.
The default setting for accesing the view is from views folder.
This addproduct form is not submitting the datat to database.
How do we change the route of different views
This addproduct form is not submitting the datat to database.
This addproduct form is not submitting the datat to database.
This addproduct form is not submitting the datat to database.

user.findOne is not a function

I am learning to use passport js in my form application and I am using a user object in an application that uses this model to save a user in database but when I return a user object that has been created and try to update that object by using findOne method I run into user.findOne is not a function error Here is my code.
Thanks in advance for helping me out.
user.js looks something like this
var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var usersSchema = new mongoose.Schema({
username:String,
password:String,
email:String
});
usersSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User",usersSchema);
my signup page looks like this
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css2?family=Mitr:wght#500&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="css/biodata.css">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<a class="navbar-brand justify-content-around" id="navbar-home" href="/">Home</a>
<div class="ml-auto" id="navbar-joint">
<a class="navbar-brand" href="/signup">Sign Up</a>
<a class="navbar-brand" href="/logout">Logout</a>
</div>
</nav>
<div class="card" id="signup-card">
<div class="card-body" id="signup-card-body">
<form action="/register" method="POST">
<h3 class="d-flex justify-content-center">SIGN UP</h3>
<div class="form-group">
<input type="text" class="form-control form-control-lg" id="username" name="username" placeholder="Username">
</div>
<div class="form-group">
<input type="email" class="form-control" id="email" name="email" placeholder="Email">
</div>
<div class="form-group">
<input type="password" class="form-control form-control-lg" id="inputPassword" name="inputPassword" placeholder="Password">
</div>
<div class="form-group">
<input type="password" class="form-control form-control-lg" id="confirminputPassword" name="confirminputPassword" placeholder="Confirm Password">
</div>
<div class="form-check">
<input type="checkbox" class="form-check-input" id="exampleCheck1" name="exampleCheck1">
<label class="form-check-label" for="exampleCheck1">I agree</label>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-lg btn-block">Submit</button>
</div>
</form>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</body>
</html>
my app.js looks like this
var express = require("express");
var app = express();
var mongoose = require("mongoose");
var passport = require("passport"),
localStrategy = require("passport-local");
const User = require("./models/User");
var expressSession = require("express-session");
mongoose.connect('mongodb://localhost/users', {useNewUrlParser: true, useUnifiedTopology: true}).catch(function(reason){
console.log('Unable to connect to the mongodb instance. Error: ', reason);
});
app.set('view engine', 'ejs');
var bod = require("body-parser");
app.use(bod.urlencoded({extended:true}));
app.use(passport.initialize());
app.use(passport.session());
app.use(expressSession({
secret:"the key",
resave:false,
saveUninitialized:false
}));
passport.use(new localStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
app.use(express.static(__dirname + '/resources'));
/*
var usersSchema = new mongoose.Schema({
username:String,
password:String,
email:String
});
var user = mongoose.model("User",usersSchema);
*/
app.get("/", function(req, res) {
res.render("home");
});
app.get("/home", function(req, res) {
res.render("home");
});
//problem method
app.post("/register",function(req,res){
var userName = req.body.username;
var inputPassword = req.body.inputPassword;
var email = req.body.email;
var exampleCheck1 = req.body.exampleCheck1;
var confirminputPassword = req.body.confirminputPassword;
if(exampleCheck1==="on"){
if(inputPassword===confirminputPassword){
User.register( new User({username:userName}),inputPassword, function(err,user){
console.log(user);
// here I tried to cast the returned object into User.js object but it didn't work
// user = new User();
if(err){
console.log(err);
return res.render("signup");
}
//I am trying to update returned object with email, I am not sure if this is the correct way to do it, would welcome suggestions. but at this point the user.findOne is not a function error is thrown.
user.findOne({username:userName},function(err,user){
user.email = email;
user.save();
console.log(user);
});
passport.authenticate("local")(req,res,function(){
res.render("bioform",{userName:userName});
});
});
}else{
console.log("Passwords doesn't match!!!");
res.render("signup");
}
}else{
console.log("Agree to Terms!!!");
res.render("signup");
}
});
//
app.get("/signup", function(req, res) {
res.render("signup");
});
app.listen(3000,function(){
console.log("Server started");
});
You are trying to call findOne in the object returned by the call to register from passport-local-moongoose.
Instead, you should call it through the User model:
const User = require("./models/User");
[...]
User.register(new User({ username: userName }), inputPassword, function(err, user) {
[...]
// Use User model instead of the object returned in User.register.
User.findOne({ username: userName }, function(err, user) {
// Your logic here.
});
});

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