push array from form reactjs - node.js

Hello i want asking about pushing array from form
This is sample my code post form to id
how to turn bellow form from post to id, to push to array.
function handleName(e) {
setInputForm({ ...inputForm, nama: e.target.value });
}
function handleJam(e) {
setInputForm({ ...inputForm, jam: e.target.value });
}
{formMode !== "" && (
<div id="form" className="card py-2 my-3 bg-secondary">
<div className="card-body">
<h4>Add </h4>
<form className="row" onSubmit={submitForm}>
<div className="col-5">
<input
type="text"
name="nama"
className="form-control mx-2"
placeholder="nama..."
value={inputForm.nama || ""}
onChange={handleName}
/>
</div>
<div className="col-2">
<input
type="text"
name="jam"
className="form-control mx-2"
placeholder="Jam ..."
value={inputForm.jam || ""}
onChange={handleJam}
/>
</div>
<div className="col-2">
<input
type="submit"
className="btn btn-success"
value="Send"
/>
</div>
</form>
</div>
</div>
)}
i can use push on postman with this way
put -> localhost:4000/kelas/update/:id
{
"$push":{
"jadwal":
[
{
"nama":"Susanti",
"jam":"12"
}
]
}
}

Related

Cannot read property 'heading' of null

My problem is I got an unexpected error at the browser end that says Cannot read property 'heading' of null
also marks this error at the client page file like about.ejs and showing; in the snap attached
I have provided all the required codes related to this. I reviewed multiple times to find for what or to where the actual errror originated but did not able to fix it.
codes of about.ejs
<%-include('./partials/header')%>
<div class="container-fluid">
<h1>About Section</h1>
<div class="card shadow mb-4">
<div class="card-header">
<form action="/admin/portfolio/create" method="post">
<button type="submit" class="btn btn-success">Edit About Page</button>
</form>
</div>
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">About Area</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<form action="/admin/about" method="post" >
<div class="form-group">
<label for="exampleFormControlInput1">Headings:</label>
<input class="form-control" type="text" name="heading" id="exampleFormControlInput1" value="<%=about.heading%>" >
</div>
<div class="form-group">
<label for="exampleFormControlInput2">Sub-Headings:</label>
<input class="form-control" type="text" name="subheading" id="exampleFormControlInput2" value="<%=about.subheading%>" >
</div>
<div class="form-group">
<textarea id="editor1" name="content" rows="10" cols="80"><%=about.content%></textarea>
</div>
<button type="submit" class="btn btn-primary">Save & Update</button>
</form>
</div>
</div>
</div>
<%-include('./partials/footer')%>
here is my router.js file
router.get('/admin/about',serverController.isAuthenticated,serverController.about)
router.post('/admin/about',serverController.isAuthenticated,serverController.about_post)
This is also my controller file
exports.about = async function(req,res){
res.render('server/about', {
about : await aboutCollection.findOne()
})
}
exports.about_post = function(req,res){
let about = new About(req.body)
about.create().then(async()=>{
res.redirect('/admin/about')
}).catch(()=>{
res.send('404')
})
}
and finally this all about my model of about page
const aboutCollection = require('../db').db().collection('about')
const objectId = require('mongodb').ObjectID
const About = function(about){
this.about = about
}
About.prototype.create = function(){
return new Promise(async(resolve,reject)=>{
await aboutCollection.updateOne({}, {$set :
{
heading : this.about.heading,
subheading : this.about.subheading,
content : this.about.content
}
})
resolve()
})
}
module.exports = About
it's because about sent value of none at the ejs tag i mean
<%= about.heading%>
Do,
exports.about = async function(req,res){
res.render('server/about', {
about : await aboutCollection.find().toArray()
})
}
Instead of,
exports.about = async function(req,res){
res.render('server/about', {
about : await aboutCollection.findOne()
})
}
In my case, I did this; after trying then see error has gone.

google recaptcha nodejs app

Ok so I am trying to implement Google Recaptcha into my register page for my app. Everything on the front end seems to work as far as it loads the page and when I click "I am not a robot" it asks me to verify images and then... when I click submit, It tells me to "Please select captcha" and it redirects me back to the register page. Thats how I have the code setup if someone doesn't select the captcha checkmark but I cannot figure out why it won't continue and create the user. Here is the code...
// handle signup logic
router.post("/register", function(req, res) {
if(req.body.captcha === undefined || req.body.captcha === "" || req.body.captcha === null){
req.flash("error", "Please select captcha");
return res.redirect("/register");
}
// secret key
var secretKey = process.env.CAPTCHA;
// Verify URL
var verifyURL = `https://www.google.com/recaptcha/api/siteverify?secret=${secretKey}&response=${req.body.captcha}&remoteip=${req.connection.remoteAddress}`;
// Make request to Verify URL
request(verifyURL, (err, response, body) => {
// if not successful
if(body.success !== undefined && !body.success){
req.flash("error", "Captcha Failed");
return res.redirect("/register");
}
// if successful
upload(req, res, function(err) {
if(err){
console.log(err.message);
req.flash("error", err.message);
return res.redirect("/register");
}
var newUser = new User({
username: req.body.username,
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
bio: req.body.bio
});
if(typeof req.file !== "undefined") {
newUser.avatar = '/uploads/userImg/' + req.file.filename;
} else {
newUser.avatar = '/uploads/userImg/no-image.png';
}
console.log(newUser);
if(req.body.adminCode === process.env.ADMINCODE) {
newUser.isAdmin = true;
}
if(req.body.answer !== process.env.SECRET){
req.flash("error", "answer the question");
return res.redirect("back");
} else {
User.register(newUser, req.body.password, function(err, user){
if(err){
console.log(err.message);
return res.render("register", {error: err.message});
}
passport.authenticate("local")(req, res, function(){
req.flash("success", "Welcome to Let's Camp " + user.username);
res.redirect("/campgrounds");
});
});
}
});
});
});
<% include ./partials/header %>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form id="register" action="/register" method="post" enctype="multipart/form-data">
<h1 class="text-center">Sign Up</h1>
</div>
<div class="row">
<div class="col-md-4 col-md-offset-2 col-xs-8 col-xs-offset-2">
<div class="form-group">
<label for="firstName">First Name</label>
<input id="firstName" class="form-control" type="text" id="firstName" name="firstName" placeholder="First Name*" required>
</div>
</div>
<div class="col-md-4 col-md-offset-0 col-xs-8 col-xs-offset-2">
<div class="form-group">
<label for="lastName">Last Name</label>
<input id="lastName" class="form-control" type="text" id="lastName" name="lastName" placeholder="Last Name*" required>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 col-md-offset-2 col-xs-8 col-xs-offset-2">
<div class="form-group">
<label for="email">Email</label>
<input id="email" class="form-control" type="email" id="email" name="email" placeholder="Email*" required>
</div>
</div>
<div class="col-md-4 col-md-offset-0 col-xs-8 col-xs-offset-2">
<div class="form-group">
<label for="avatar">Avatar Image URL</label>
<input id="avatar" class="form-control" type="file" name="avatar">
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 col-md-offset-2 col-xs-8 col-xs-offset-2">
<div class="form-group">
<label for="username">Username</label>
<input id="username" class="form-control" type="text" id="username" name="username" placeholder="Username*" required>
</div>
</div>
<div class="col-md-4 col-md-offset-0 col-xs-8 col-xs-offset-2">
<div class="form-group">
<label for="password">Password</label>
<input id="password" class="form-control" type="password" id="password" name="password" placeholder="Password*" required>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2 col-xs-8 col-xs-offset-2">
<div class="form-group">
<label for="bio">Bio</label>
<textarea id="bio" class="form-control" type="bio" name="bio" rows="5" placeholder="Write a short description of yourself and what you enjoy about camping."></textarea>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 col-md-offset-2 col-xs-8 col-xs-offset-2">
<div class="form-group">
<label for="adminCode">Admin Code</label>
<input id="adminCode" class="form-control" type="text" name="adminCode" placeholder="Admin Code">
</div>
</div>
<div class="col-md-4 col-md-offset-0 col-xs-8 col-xs-offset-2">
<div class="form-group">
<label for="number">Enter: Answer</label>
<input id="number" class="form-control" type="text" id="answer" name="answer" placeholder="Answer*" required>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="g-recaptcha form-group" data-sitekey="6LduxzsUAAAAAAoten8FA_zg12PjA3QfSjF5vFvY"></div>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2 col-xs-8 col-xs-offset-2">
<div class="form-group">
<button class="btn btn-lg btn-primary btn-block">Sign Up!</button>
</div>
Go Back
</form>
</div>
</div>
<div class="row">
<div class="col-md-12 col-xs-8 col-xs-offset-2">
<p class="text-center"><strong>*</strong> indicates a required field.</p>
</div>
</div>
</div>
<% include ./partials/footer %>
It's not req.body.captcha
Seems like You've not read tutorial correctly.
From this tutorial is see such example:
app.post('/submit',function(req,res){
// g-recaptcha-response is the key that browser will generate upon form submit.
// if its blank or null means user has not selected the captcha, so return the error.
if(req.body['g-recaptcha-response'] === undefined || req.body['g-recaptcha-response'] === '' || req.body['g-recaptcha-response'] === null) {
// not passed validation
}
And from this file is see such code at line 52 :
if(req.body && req.body['g-recaptcha-response']) response = req.body['g-recaptcha-response'];
Both of them proves that "invisible" field is accessible under req.body['g-recaptcha-response']
HERE IS THE FIX:
this:
const captcha = req.body['g-recaptcha-response'];
if(!captcha){
req.flash("error", "Please select captcha");
return res.redirect("/register");
}
and this:
// Verify URL
var verifyURL = `https://www.google.com/recaptcha/api/siteverify?secret=${secretKey}&response=${captcha}&remoteip=${req.connection.remoteAddress}`;
or just create simple middleware catchReCaptcha and attach to router:
// middleware that catches g-recaptcha-response and puts in req.body.captcha
const catchReCaptcha = (req, res, next) => {
if(req.body && req.body['g-recaptcha-response']) {
req.body.captcha = req.body['g-recaptcha-response'];
}
next();
};
// attached middleware to register route
router.post("/register", catchReCaptcha, (req, res) => {
but keep in mind You'll have conflicts of parsing multipart/form-data since upload method responsible also for parsing body of request for that content-type.

Logic doesn't work after .then

I have a Login end point that respond me a json.
I'm using vue-router to do a POST and then Store a token in localStorage, but after the POST, the json shows on the screen:
{"success":false,"message":"Login ou senha inválidos!"}
It should return on the page login, with the message
This is the code:
var vmLogin = new Vue({
el: '#login',
data: {
email: '',
msg: '',
password: ''
},
beforeCreate: function () {
if(localStorage.getItem("timeTaskToken") !== null) {
window.location.href = '/'
}
},
methods: {
getLogin: function (e) {
this.$http.post('/login', {email: this.email, password: this.password}).then((response) => {
alert('teste!');
if(response.body.success === true) {
localStorage.setItem("timeTaskToken", response.body.token);
window.location.href = '/'
} else {
this.msg = response.body.message
}
}, (response) => {
// error callback
});
e.preventDefault();
}
}
});
login page
<form id="login" class="form-horizontal" method="post">
<h3>{{ msg }}</h3>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">Email</label>
<div class="col-sm-10">
<input type="email" v-model="email" class="form-control" name="email" placeholder="Email">
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Password</label>
<div class="col-sm-10">
<input type="password" v-model="password" class="form-control" name="password" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label>
<input type="checkbox"> Remember me
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default" #click="getLogin">Sign
in</button>
</div>
</div>
</form>
It's like nothing after .then works...
The returned JSON just appear in the screen.
I expect the problem is that the Sign In button is a submit button and you just want it to be a button button.
Change
<button type="submit" class="btn btn-default" #click="getLogin">Sign in</button>
To
<button type="button" class="btn btn-default" #click="getLogin">Sign in</button>
Note the type="button".
If you leave it as type submit then the form is is actually posted and code execution will stop. This also explains why you see a page that has just the JSON result; that is just the response from posting that form.
Alternatively, move e.preventDefault() to the top of the method.
You could also use #click.prevent="getLogin".
Just add a console.error in you error callback
}, (response) => {
console.error(response);
});
This is the first step because maybe you just enter here ..

How to update a record using Sequelize?

I am trying to update the records form a table by using Sequelize.
Unfortunately, the id of the event I am trying to update seems to be undefined. How can I send it correctly?
The block of code I have in my controller looks like this:
router.get('/edit/:eventid', function(req, res) {
var eventid = req.params.eventid;
Event.findById(req.params.eventid).then(function(event) {
eventid= event.eventid;
title= event.title;
description= event.description;
availabletickets=event.availabletickets;
date= event.date;
newDate= date.toString();
newdate= newDate.substring(0,21);
console.log(eventid);
}) .then(function() {
res.render('eventEdit', {
eventid: eventid,
pagetitle: ' Edit Event',
title: title,
description:description,
availabletickets:availabletickets,
newdate: newdate,
});
})
.catch(function(error) {
res.render('error', {
error: error
});
});
});
router.post('/edit', function(req, res){
var eventid = req.body.eventid;
var title = req.body.title;
var description = req.body.description;
var availabletickets= req.body.availabletickets;
var date = req.body.date;
console.log( eventid); //this returns undefined.
console.log('title, description, availabletickets, date);
const newData = {
title: title,
date: date,
description: description,
availabletickets: availabletickets
};
Event.update(
newData,
{
where:{
eventid:eventid
}
}
).then(function() {
console.log("Event updated");
res.redirect('/events');
}).catch(e => console.error(e));
});
Although, the HTML file,where the user introduces the values when editing the events, looks like this:
<div class="container">
<h2><%= pagetitle %> </h2>
<form method="post" action="/events/edit">
<div class="container">
<div class="col-md-12 ">
<div class="row">
<div class="col-md-12 ">
<input class="form-control" type="text" name="title" id="title" value="<%= title %>" placeholder="Titlu Eveniment" required="true">
<p style="color:#8B0000;"><small>*This field is mandatory</small></p>
<textarea rows=7 class="form-control" type="text" name="description" id="description" placeholder="Descriere Eveniment"><%= description %></textarea> <br>
<input class="form-control" type="text" name="availabletickets" id="availabletickets" value="<%= availabletickets %>"> <br>
<label> Data:<%= newdate %> </label> <br/>
<label>Cahnge event date:</label>
<input class="form-control" type="date" name="date" id="date" style="width:190px;" ><br>
<button class="btn" id="addValue" style="background-color:#8B0000; color:white;">Save</button>
<button class="btn btn-warning">Cancel</button>
</div>
</div>
</div>
</div>
</form>
</div>
You get the eventid as undefined because req.body doesn't contain the eventid (it's not passed from the client side). To pass it from the client side you have to add an input having the name="eventid" attribute.
In the EJS template you need to render the eventid value as a hidden input (<input type="hidden" ...)
You can do that by added in your form this line:
<input type="hidden" value="<%= eventid %>" name="eventid" />
This is the updated form code:
<div class="container">
<h2><%= pagetitle %> </h2>
<form method="post" action="/events/edit">
<input type="hidden" value="<%= eventid %>" name="eventid" />
<div class="container">
<div class="col-md-12 ">
<div class="row">
<div class="col-md-12 ">
<input class="form-control" type="text" name="title" id="title" value="<%= title %>" placeholder="Titlu Eveniment" required="true">
<p style="color:#8B0000;"><small>*This field is mandatory</small></p>
<textarea rows=7 class="form-control" type="text" name="description" id="description" placeholder="Descriere Eveniment">
<%= description %>
</textarea>
<br>
<input class="form-control" type="text" name="availabletickets" id="availabletickets" value="<%= availabletickets %>">
<br>
<label> Data:
<%= newdate %>
</label>
<br/>
<label>Cahnge event date:</label>
<input class="form-control" type="date" name="date" id="date" style="width:190px;">
<br>
<button class="btn" id="addValue" style="background-color:#8B0000; color:white;">Save</button>
<button class="btn btn-warning">Cancel</button>
</div>
</div>
</div>
</div>
</form>
</div>

nodemailer doesn't stop sending mails

I have a simple nodemailer setup that sends emails without a problem. The only thing I can't figure out is how to stop it from sending once it started. I click send, it sends an email but the page keeps loading and soon I receive another email etc. Surely it should only send one email and close the process.
Can anybody see something I'm doing wrong here?
var smtpTransport = nodemailer.createTransport('SMTP', {
host: 'mail.francotanzarella.com',
secureConnection: false,
port: 587,
auth: {
user: 'contact#francotanzarella.com',
pass: '***'
}
});
app.post('/contact', function(req, res) {
var htmlTpl = '<h4>Message from' + ' ' + req.body.name + '</h4><p><span>' + req.body.email + '</span</p><p>' + req.body.message + '</p>';
mailOptions = {
from: 'noreply#francotanzarella.com',
to: 'contact#francotanzarella.com',
subject: 'New message from francotanzarella.com',
html: htmlTpl,
debug: true
}
smtpTransport.sendMail(mailOptions, function(error, response) {
if(error) {
console.log(error)
} else {
console.log(response.message);
}
smtpTransport.close();
});
});
contact.ejs
<form id="contact-form" method="POST" name="userForm" action="/contact" ng-submit="submitForm(userForm.$valid)" novalidate>
<div class="row">
<div class="small-12 column">
<div class="row" ng-class="{ 'error' : userForm.name.$invalid && !userForm.name.$pristine && submitted }">
<div class="small-12 column">
<label for="name" class="inline">Name</label>
</div>
<div class="small-12 column">
<input type="text" id="name" name="name" placeholder="Your name" ng-model="name" required />
<small class="error" ng-show="userForm.name.$invalid && !userForm.name.$pristine">Please enter your name</small>
</div>
</div>
<div class="row" ng-class="{ 'error' : userForm.email.$invalid && !userForm.email.$pristine && submitted }">
<div class="small-12 column">
<label for="email" class="inline">Email</label>
</div>
<div class="small-12 column">
<input type="email" id="email" name="email" placeholder="Your email" ng-model="email" required />
<small class="error" ng-show="userForm.email.$invalid && !userForm.email.$pristine">I need a valid email please</small>
</div>
</div>
<div class="row" ng-class="{ 'error' : userForm.message.$invalid && !userForm.message.$pristine && submitted }">
<div class="small-12 column">
<label for="message" class="inline">Message</label>
</div>
<div class="small-12 column">
<textarea id="message" name="message" placeholder="Send me a message" ng-model="message" required></textarea>
<small class="error" ng-show="userForm.message.$invalid && !userForm.message.$pristine">What? No message?</small>
</div>
</div>
<div class="row">
<div class="small-12 column">
<button type="submit" class="button" ng-disabled="userForm.$invalid">send</button>
</div>
</div>
</div>
</div>
<div id="form-response-container">
<div id="for-response-inner">
<h3 id="form-response"></h3>
</div>
</div>
</form>
Okay I fixed this. Not sure if it's the correct method but it works. I basically pass the browser a ok (200) when the email was sent successfully.
if(error) {
res.send(500);
} else {
res.send(200);
}

Resources