POST method not inserting into users array - javascript

Im trying to figure out why my post Method won't insert the user made in the register form into my user array, and no array is logged in node. When the register button is clicked, the site is also not redirecting to the /login page. Im not looking for the exact solution maybe just a tip to help me on the right path.
(all libraries is required)
The POST method im using
const express = require('express')
const app = express()
const bcrypt = require('bcrypt');
// helps finding specifik path
const path = require('path')
const port = 3000
// users array
const users = [];
app.use(express.static('views'))
app.listen(port,()=>{
console.log("App is listening on port 3000")
});
// VIGTIGT: tilader at vi kan hente data fra forms via "Name" tagget i formen!
app.use(express.urlencoded({ extended: false }))
// req router fra .auth/user_auth
// Routing: We are mapping to a special respond, and responds a HTML filer
app.get('/contact',(req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/contact.html'))
})
app.get('/login',(req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/login.html'))
})
app.get('/register',(req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/register.html'))
})
app.get('/home',(req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/home.html'))
})
app.get('/portfolio',(req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/portfolio.html'))
})
app.get('/adminpage', (req,res)=>{
res.sendFile(path.resolve(__dirname,'./html/adminpage.html'))
})
// post metoder fra form
app.post('/register', async (req, res)=>{
try{
const hashedPassword = await bcrypt.hash(req.body.password, 10)
users.push({
id: Date.now().toString(),
name: req.body.username,
email: req.body.email,
password: hashedPassword
})
res.redirect('/login')
} catch{
res.redirect('/register')
}
console.log(users)
})
form im using
<form>
<div class="container">
<h1>Register</h1>
<p>Please fill in this form to create an account.</p>
<hr>
<label for="username"><b>Username</b></label>
<input type="text" placeholder="Enter username" name="username" required>
<label for="email"><b>Email</b></label>
<input type="text" placeholder="Enter Email" name="email" required>
<label for="psw"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="password" required>
<hr>
<p>By creating an account you agree to our Terms & Privacy.</p>
<button href="/login" type="submit" class="registerbtn">Register</button>
</div>
<div class="container signin">
<p>Already have an account? Sign in.</p>
</div>
</form>

Firstly, you need to specify a method and an action to determine where the data is being sent to:
<form action="/register" method="POST">
</form>
Secondly, you are not parsing the incoming data when it is received by your server. The req.bodysyntax implies that the data is received as an object/JSON, but I don't see anything in your code that indicates you are doing this.
You can use one of a number of packages to do this for you, and Express has built-in middleware for this purpose. I'd recommend the body-parser package.
const bodyParser = require('body-parser');
app.use(express.json())
app.use(bodyParser.urlencoded({ extended: true }))
Worth adding a temporary console.log(req.body) to your function too just to check form data is being received as intended.

Related

Contact form using nodemailer is not working

I have created a contact form and trying to use nodemailer to send the message to my email, but not sure where is the issue.
I created a server.js and put it in the main folder while Mailer.js that contain the form in components
I am not sure how the server know that I want to use the form
this is my first project on React and I think I still don't understand some basics of React
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', (req, res) => {
const output = `
<p>You have a new contact request</p>
<h3>Contact Details</h3>
<ul>
<li>Name: ${req.body.name}</li>
<li>Email: ${req.body.email}</li>
</ul>
<h3>Message</h3>
<p>${req.body.message}</p>
`;
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL, // generated ethereal user
pass: process.env.PASSWORD // generated ethereal password
},
tls:{
rejectUnauthorized:false
}
});
// setup email data with unicode symbols
let mailOptions = {
from: process.env.EMAIL, // sender address
to: email, // list of receivers
subject: 'Node Contact Request', // Subject line
text: 'Hello world?', // plain text body
html: output // html body
};
// send mail with defined transport object
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error);
}
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...'));
This is the form
import React from 'react';
import "./Mailer.scss";
const Mailer = () =>{
return (
<div className="container">
<div className="section ContactPage">
<div className="ContactPage-banner">
<h1 className="ContactPage-banner__title">Contact Us</h1>
</div>
<div className="ContactPage-content">
<form method="POST" className="form" action="send">
<div className="row">
<label className="labels">Name</label>
<input type="text" name="name" className="input"/>
</div>
<div className="row">
<label className="labels">Email</label>
<input type="email" name="email" className="input"/>
</div>
<div className="row">
<label className="labels">Message</label>
<textarea name="message" rows='4' className="input"/>
<input type="submit" value="Send"/>
</div>
</form>
</div>
</div>
</div>
);
};
export default Mailer;
this is what I get when I click on SEND
From what I could gather, you're posting to the wrong URL.
In your server app, you create a post handler for /send
However, in your React App, you post to /xxxxx/send (You obscured the xxxxx part)
I advise that you replace your
<form method="POST" className="form" action="send">
With
<form method="POST" className="form" action="http://127.0.0.1:3000/send">
And try again

How to fix a "reload page loop" when using a post method in Node JS?

Given the following html form:
<form class = "new-date" method = "POST" action = "http://localhost:5600/postDate">
<h3>Owner</h3>
<input type ="text" name = "ownerName" class = "form-element global" id="owner">
</select>
<h3>Pet</h3>
<input type = "text" name = "petName" class = "form-element global" id = "pet">
</select>
<h3>Schedule the date</h3>
<input type="date" id="birthday" name="birthday" class = "form-element global" id="date">
<h3>Description</h3>
<textarea class = "form-element description-text" placeholder= "What is wrong with your pet?" name ="problem" ></textarea id="problem"><br>
<input type="submit" class = "form-element btn" value="Add">
</form>
Im trying to make a post method that is located inside my server.js (Node):
const exp = require('express');
const path = require('path');
var bodyParser = require('body-parser');
const app = exp();
/*DATABASE AND QUERIES*/
const mysql = require("mysql2");
var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "admin",
database: "control_clientes",
connectionLimit: 5
});
app.use(bodyParser.urlencoded());
app.use(bodyParser.json());
app.post('/postDate', (req, res)=>{
console.log(req.body.ownerName); //TO CHECK IF IM RECEIVING THE DATA. IT WORKS
});
After submitting and sending the client side data to my server, the html page is not properly doing the reload task:
As can see in this image, the reload thing is still going. I'm not sure why it does that.
Im new to Node JS, do you have any idea what is going on with the unfinished reload thing?
Try this
app.post('/postDate', (req, res)=>{
console.log(req.body.ownerName); //TO CHECK IF IM RECEIVING THE DATA. IT WORKS
res.json({message: 'OK.'})
});
If you want your browser to stop spinning (loading) you need to send a response from a server.
For example send a json response with req.body (echo endpoint)
app.post('postDate', (req, res) => {
console.log(req.body.ownerName);
res.json(req.body);
})

Routing issue with express.js and nodemailer

Hi I am attempting to use nodemailer with gmail to create a contact form on my website however, I believe there is a routing issue that is causing the mail to be sent but I cannot mange to fix it.
My about.html page contains the code form below:
<form id="contact" action="/contact" id="contact-form" method="post" role="form">
<h3>Contact Form</h3>
<fieldset>
<input placeholder="Your name" type="text" tabindex="1" id="name" name="name" required autofocus>
</fieldset>
<fieldset>
<input placeholder="Subject" type="text" tabindex="1" id="subject" name="subject" required>
</fieldset>
<fieldset>
<input placeholder="Your Email Address" type="email" tabindex="2" id="email" name="email" required>
</fieldset>
<fieldset>
<textarea placeholder="Type your message here...." tabindex="5" id="message" name="message" required></textarea>
</fieldset>
<fieldset>
<button name="submit" type="submit" id="contact-submit" data-submit="...Sending">Submit</button>
</fieldset>
</form>
And my app.js file that is the node server contains the code
//safe enviroment variables
require('dotenv').config();
//express routing
var express = require("express");
var app = express();
var router = express.Router();
var path = __dirname + '/views/';
app.use(express.static('public'));
router.use(function (req,res,next) {
console.log("/" + req.method);
next();
});
router.get("/",function(req,res){
res.sendFile(path + "index.html");
});
router.get("/about",function(req,res){
res.sendFile(path + "about.html");
});
app.use("/",router);
app.use("*",function(req,res){
res.sendFile(path + "404.html");
});
app.listen(8080, function () {
console.log('Example app listening on port 8080!')
})
//nodemail
const nodemailer = require('nodemailer')
const bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({extended: true}))
//collecting gmail username and password
const GMAIL_USER = process.env.GMAIL_USER
const GMAIL_PASS = process.env.GMAIL_PASS
// POST route from contact form
app.post("/contact", (req, res) => {
async function main() {
// Instantiate the SMTP server
const smtpTrans = nodemailer.createTransport({
service: 'Gmail',
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: GMAIL_USER,
pass: GMAIL_PASS
}
})
// Specify what the email will look like
const mailOpts = {
from: GMAIL_USER , // This is ignored by Gmail
to: GMAIL_USER,
subject: `${req.body.subject}`,
text: `${req.body.name} (${req.body.email}) says: ${req.body.message}`
}
// Attempt to send the email
smtpTrans.sendMail(mailOpts, (error, response) => {
if (error) {
console.log('error email')
res.sendFile(path + "index.html"); // Show a page indicating failure
}
else {
console.log('email sent')
res.sendFile(path + "about.html"); // Show a page indicating success
}
})
}
})
However when clicking the submit button the form it send me to the 404 page indicating that the form cannot find the post function since if it could then it would not redirect me to the post function. I have also added echos into the function to print to console if it is called which does not happen. I have tried changing the routing but can't seem to get it to work.

Form is not submitting in node

I am trying to make a post request from a html form and cant figure out where im going wrong.
> <form action="/api" method="POST">
<label for="username">username or email address</label>
<input name="username" id="username" type="text">
<label for="password">password</label>
<input id="password"name="password" type="text">
<button >Log in</button>
</form>
here is my main javascript file for the html (not the server)
"use strict"
let options = {
headers:{
"Content-Type" : "application/json"
},
method: "POST",
}
// fetch("/api",options)
And here is my node js server
"use strict"
//Installing express
let express = require(`express`)
let app = express()
app.use(express.json())
//running the server
app.listen(3000,()=>{
console.log("server is running boi");
})
//Middleware to load the static content
app.use(express.static(`public`))
//Database stuff
let Datastore = require('nedb')
let db = new Datastore({ filename: 'database.db' });
db.loadDatabase()
db.insert({username:"sid", password:"westham"})
//Handler for any post requests made
app.post(`/api`,(req,res)=>{
console.log("request was made");
console.log(req.body);
})
Two Observations
No middleware found in your server.js file for handling form data,
use body-parser http://expressjs.com/en/resources/middleware/body-parser.html
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true });
In your html form, if you're not submitting form with JavaScript then mentiod button type as submit
<button type="submit" >Log in</button>

directing a specific input in a form to update an array in MongoDB

so i have a form with multiple inputs, the form creates a post request on the server. I need a specific input in my html to push a value into an array thats stored in the schema. I understand that the request pertains to a specific route, and that all inputs react to this route as one, is there a way to break them up without creating a new post route for each input. The rateEmployee function is part of an exported object.
rateEmployee: function(req, res){
var employeeId = req.params.id
Employees.findByIdAndUpdate(employeeId, {$push: {ratings: 1}}, {new: true}, (err, update) => {
if(err){
console.log(err)
}
else {
console.log(update)
res.redirect('/employers/view/' + req.user.id)
}
<form method='post' action='/employers/<%= employee.id %>/employeeRate'>
<div>Rate This Employee</div>
<i class="glyphicon glyphicon-thumbs-down"></i>
<input type='submit' id='one' value='1'>
<input type='submit' id='two' value='2'>
<input type='submit' id='three' value='3'>
<input type='submit' id='four' value='4'>
<input type='submit' id='five' value='5'>
<i class="glyphicon glyphicon-thumbs-up"></i>
</form>
Express's router are middlewares that bind to a specific route.You can bind multiple middlewares to the same route.
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
const express = require('express');
const router = express.Router();
router.post('/post1', (req, res,next) => {
let body=req.body;
let rate = body.rate;
next();
});
router.post('/post1', (req, res) => {
res.json({status: 'success'});
});
They all will be called in order if you are passing the control by calling next().
If you decided to break the chain then an response can be returned at any point, res.json({//response});.
So your form can pass any arbitrary no. of inputs to the same route but your middlewares bind to that route must have logic to decide who has the responsibility to handle the incoming request. To access your form data first register a proper parser (Json/url encoded) and then the data posted from your form will be available in your req.body.This data will be available to all the middlewares you pass through.
EDIT : Adding body parser and improving example

Categories