Error Uploading File Using multer - node.js

I am trying to create a WebApp where a user can upload his profile pic from the profile page. I am using MEAN Stack and uploading file using multer.
Here is my code for CLIENT VIEW
<div class="col-xs-8 vn-right-pane">
<h1>Profile</h1>
<form class="form-horizontal" enctype="multipart/form-data">
<div class="form-group">
<label for="first">First Name</label>
<div class="input-group">
<span class="input-group-addon">
<i class="glyphicon glyphicon-option-horizontal"></i>
</span>
<input ng-model="model.navigatedUser.firstName"
id="first"
class="form-control"
type="text"
placeholder="First Name"/>
</div>
<label for="last">Last Name</label>
<div class="input-group">
<span class="input-group-addon">
<i class="glyphicon glyphicon-option-horizontal"></i>
</span>
<input ng-model="model.navigatedUser.lastName"
id="last"
class="form-control"
type="text"
placeholder="Last Name"/>
</div>
<label for="email">Email</label>
<div class="input-group">
<span class="input-group-addon">
<i class="glyphicon glyphicon-envelope"></i>
</span>
<input ng-model="model.navigatedUser.email"
id="email"
class="form-control"
type="email"
placeholder="Email"/>
</div>
<label>Username</label>
<div class="input-group">
<span class="input-group-addon">
<i class="glyphicon glyphicon-user"></i>
</span>
<input ng-model="model.navigatedUser.username"
class="form-control"
type="text"
placeholder="Username"/>
</div>
<label>Profile Image</label>
<div class="input-group">
<span class="input-group-addon">
<i class="glyphicon glyphicon-upload"></i>
</span>
<input name='myFile'
type='file'
class="form-control">
</div>
<label>Phone Number</label>
<div class="input-group">
<span class="input-group-addon">
<i class="glyphicon glyphicon-phone"></i>
</span>
<input ng-model="model.navigatedUser.phone"
class="form-control"
type="text"
placeholder="Phone Number"/>
</div>
<a ng-click="model.deleteUser(model.navigatedUser)"
class="btn btn-warning btn-block">
Unregister
</a>
<a ng-click="model.updateUser(model.navigatedUser)"
class="btn btn-primary btn-block">
Update
</a>
<a type="submit"
ng-click="model.uploadImage(model.navigatedUser)"
class="btn btn-primary btn-block">
Upload
</a>
<a ng-click="model.logout()"
class="btn btn-danger btn-block">
Logout
</a>
</div>
</form>
<div class="alert alert-danger" ng-show="model.error">
{{model.error}}
</div>
<div class="alert alert-success" ng-show="model.message">
{{model.message}}
</div>
</div>
Here is the code for uploadImage function in the controller:
function uploadImage(user) {
UserService
.uploadImage(vm.navigateUserId, user)
.then(function (response) {
if (response.data) {
$route.reload();
}
else {
alert("Error updating user information!")
}
});
}
Below is the client side service request from SERVICE.CLIENT. This uses UserService
function uploadImage(userId, user) {
return $http.post("/api/project/upload/"+ userId, user);
}
And lastly Below is my Server side code for uploading Image. in SERVICE.SERVER
var multer = require('multer');
var upload = multer({ dest: __dirname+'/../../public/uploads' });
app.post("/api/project/upload/:id",upload.single('myFile'),uploadImage);
function uploadImage(req, res) {
var myFile = req.file;
var userId = req.params.id;
var originalname = myFile.originalname; // file name on user's computer
var filename = myFile.filename; // new file name in upload folder
var path = myFile.path; // full path of uploaded file
var destination = myFile.destination; // folder where file is saved to
var size = myFile.size;
var mimetype = myFile.mimetype;
projectUserModel
.findUserById(userId)
.then(function (userData) {
userData.imgUrl = '/uploads/'+filename;
userData.save();
var callbackUrl="/project/#/user/"+userId;
res.redirect(callbackUrl);
},function (error) {
res.sendStatus(404);
return;
});
}
Logically I feel like my approach is correct but I just cannot get it to work.
I always get undefined for myFile in uploadImage function. It is unable to fetch the file from req.file;
Please help me I am stuck on this for a long time. Thank You in Advance.

Related

Node js Dropzone js - Upload file without submitting form

I am new in node js and trying to integrate single file upload using dropzone js. I want to upload image before submitting form. I have managed to call the upload action before submitting.
Here is my html code:
<form id="add_user" name="add_user" class="form-horizontal" action="/add-new-user" method="POST">
<div class="directory-bg text-center">
<div class="directory-overlay">
<span id="imageuploader">
<input name="profileimg" id="profileimg" type="hidden" value="">
<img id="ws_user_avatar" class="rounded-circle thumb-lg img-thumbnail dropzone" data-thumb="public/assets/images/users/user.png" src="public/assets/images/users/user.png" alt="Generic placeholder image">
<!--<div class="fallback">
<input name="image" id="image" type="file">
</div>-->
x
</span>
</div>
</div>
<div class="directory-content p-4">
<div class="mt-4">
<% if(success != "") {%>
<div class="alert alert-success" role="alert">
<strong>Done!</strong> <%= success %>
</div>
<% } %>
<div class="row">
<div class="col-md-12">
<div class="mb-3">
<label class="form-label" for="email">Email Address</label>
<input type="email" class="form-control" name="email" id="email" placeholder="Email Address" data-key="Email Address" autocomplete="off" autofill="false">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label" for="fname">First Name</label>
<input type="text" class="form-control" name="fname" id="fname" placeholder="First Name" data-key="First Name" autocomplete="off" autofill="false">
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label" for="lname">Last Name</label>
<input type="text" class="form-control" id="lname" name="lname" placeholder="Last Name" data-key="Last Name" autocomplete="off" autofill="false">
</div>
</div>
</div>
</div>
</div>
</form>
Here is the js code to handle dropzone event
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone(".dropzone", {
url: '/upload-image',
autoProcessQueue: false,
uploadMultiple: false,
maxFiles:2,
maxFilesize: 2,
createImageThumbnails:false,
hiddenInputContainer: "img.rounded-circle",
init: function(file) {
var prevFile = null;
this.on("addedfile", function(file) {
var $this = this;
setTimeout(function () {
if(file.status == "error"){
alert(file.previewTemplate.innerText);
} else {
if(prevFile){
$this.removeFile($this.files[0])
}
prevFile = file;
$("#user_avatar").attr('data-imgname', file.name);
previewImage($this);
}
}, 10);
});
}
});
function previewImage(input){
let fileReference = input.files && input.files[0];
if(fileReference){
var reader = new FileReader();
reader.onload = (event) => {
document.getElementById('user_avatar').src = event.target.result;
}
reader.readAsDataURL(fileReference);
}
}
$(document).on('click','#btn_submit', function(e){
e.preventDefault();
if(myDropzone.getQueuedFiles().length > 0){
myDropzone.processQueue();
} else {
$("#add_user").submit();
}
});
Here is the post handler code in router.js file:
const express = require('express');
const router = express.Router();
router.post('/upload-image', function(req, res){
console.log('requested inage',req.files.file.path);
// fs.readFile(request.files.file.path, function(err, data) {
// var newPath = __dirname + "/public/img/xspectra/customlogo.png";
// fs.writeFile(newPath, data, function (err) {
// console.log("Finished writing file..." + err);
// response.redirect("back");
// });
// });
});
When the dropzone myDropzone.processQueue() function called, I get an error message in the post handler function TypeError: Cannot read property 'file' of undefined.
Can anyone suggest me where I am doing wrong?
Many Thanks!
That means that the file uploaded didn't properly make it to your web server. Are you using express-fileupload on the nodejs side to handle the uploads?
If so, I recommend checking out this link on a really great tutorial

Render updated document to ejs page mongoose node js

I have an app where users can create an account and update their information after creation. I am able to save the updated document to the database when users input new information on the edit page, however, when I redirect them to the user panel, the old information is still being displayed. I believe that it has something to do with the session that gets created on login because the updated information only shows once the user logs out and logs back in.
This is my edit page:
<%- include('partials/header') %>
<% if(user.firstName.endsWith("s")) { %>
<h1 class="dashboard-title"><%=user.firstName + "' Account"%></h1>
<% } else { %>
<h1 class="dashboard-title"><%=user.firstName + "'s Account"%></h1>
<% } %>
<!-- Action Buttons -->
<div class="container">
<div class="row justify-content-center">
<div class="col-md-3">
<a href="/logout" class="dashboard-btn">
<h5>Logout <i class="fas fa-door-open"></i></h5>
</a>
</div>
<div class="col-md-3">
<a href="/edit" class="dashboard-btn">
<h5>Edit <i class="fas fa-edit"></i></h5>
</a>
</div>
</div>
</div>
<br>
<!-- Information -->
<div class="container">
<form class="" action="/edit" method="post">
<div class="row justify-content-center">
<label class="col-form-label col-md-1" for="firstName">First Name:</label>
<div class="form-group col-md-7">
<input name="firstName" class="form-control" type="text" value="<%=user.firstName%>" >
</div>
</div>
<br>
<div class="row justify-content-center">
<label class="col-form-label col-md-1" for="lastName">Last Name:</label>
<div class="form-group col-md-7">
<input name="lastName" class="form-control" type="text" value="<%=user.lastName%>" >
</div>
</div>
<br>
<div class="row justify-content-center">
<label class="col-form-label col-md-1" for="email">Email:</label>
<div class="form-group col-md-7">
<input name="email" class="form-control" type="text" value="<%=user.username%>" readonly>
</div>
</div>
<br>
<div class="row justify-content-center">
<label class="col-form-label col-md-1" for="phone">Phone:</label>
<div class="form-group col-md-7">
<input name="phone" class="form-control" type="text" value="<%=user.phoneNumber%>" >
</div>
</div>
<br>
<div class="row justify-content-center">
<label class="col-form-label col-md-1" for="address">Address:</label>
<div class="form-group col-md-7">
<input name="address" class="form-control" type="text" value="<%=user.personalInfo.address%>" >
</div>
</div>
<br>
<div class="row justify-content-center">
<label class="col-form-label col-md-1" for="coverage">Coverage:</label>
<div class="form-group col-md-7">
<input name="coverage" class="form-control" type="text" value="<%=user.coverage%>" >
</div>
</div>
<br>
<div class="row justify-content-center">
<label class="col-form-label col-md-1" for="paymentPlan">Payment:</label>
<div class="form-group col-md-7">
<input name="paymentPlan" class="form-control" type="text" value="<%=user.paymentPlan%>">
</div>
</div>
<br>
<button class="btn register-btn" type="submit">Submit Changes</button>
</form>
</div>
<%- include('partials/footer') %>
And app.js to handle the post requests to edit route:
app.get("/user-panel", function(req, res) {
if(req.isAuthenticated()) {
res.render("user-panel", {
user: req.user
});
} else {
res.redirect('/login');
}
});
app.get("/edit", function(req, res) {
if(req.isAuthenticated()) {
res.render("edit", {
user: req.user
});
} else {
res.redirect("/login");
}
});
app.post("/edit", function(req, res) {
const email = req.user.username;
const firstName = req.body.firstName;
const lastName = req.body.lastName;
const phone = req.body.phone;
User.findOne({username: email}, function(err, foundUser) {
if(err) {
console.log(err);
} else {
if (foundUser) {
foundUser.firstName = firstName;
foundUser.save();
res.redirect("/user-panel");
}
}
});
});
Any ideas on how I can get the server to respond with the updated info without having to log out the user?
I want to touch on a few things.
to answer your question, you need to query the database again upon redirect. like so:
you need to pass the email value back to the original user-panel function:
res.redirect("/user-panel?username=" + email);
then, you have to query the database again, like so:
app.get("/user-panel", authCheck, function(req, res) {
let email = req.query.email
User.findOne({username: email}, function(err, foundUser) {
if(err) {
console.log(err);
} else {
if (foundUser) {
foundUser.firstName = firstName;
foundUser.save();
res.render("user-panel", {
user: req.user
});
}
}
});
});
You should try not to use authentication logic within each function, rather have it as a seperate function and import it as middleware. Makes it cleaner. I've rewritten it for you.
function authCheck(req, res, next) {
if(req.isAuthenticated()) {
next()
} else {
res.redirect('/login');
}
}
now within any new function you create (within this file), you can just use the function authCheck() as middleware:
app.get('/', authCheck, (req, res) => {

image doesnt upload using multer

Ok so in my app I am trying to allow image uploading using multer. My app is built using node.js and my database is using mongodb. When I create an account and select an image for the avatar image, it creates the account but automatically uses the no-image.png file I have setup in case someone doesn't select an image. Here is the code... Any help will be awesome.
// handle signup logic
router.post("/register", function(req, res) {
upload(req, res, function(err) {
if(err){
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){
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");
});
});
}
});
});
var multer = require("multer");
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, './public/uploads/userImg');
},
filename: function(req, file, callback) {
callback(null, Date.now() + file.originalname);
}
});
var upload = multer({ storage : storage}).single('image');
<% include ./partials/header %>
<div class="row">
<div class="col-xs-8 col-xs-offset-2">
<form action="/register" method="post">
<h1 class="text-center">Sign Up</h1>
</div>
<div class="row">
<div class="col-xs-4 col-xs-offset-2">
<div class="form-group">
<label for="firstName">First Name</label>
<input id="firstName" class="form-control" type="text" name="firstName" placeholder="First Name*" required>
</div>
</div>
<div class="col-xs-4 col-xs-offset-0">
<div class="form-group">
<label for="lastName">Last Name</label>
<input id="lastName" class="form-control" type="text" name="lastName" placeholder="Last Name*" required>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-4 col-xs-offset-2">
<div class="form-group">
<label for="email">Email</label>
<input id="email" class="form-control" type="email" name="email" placeholder="Email*" required>
</div>
</div>
<div class="col-xs-4 col-xs-offset-0">
<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-xs-4 col-xs-offset-2">
<div class="form-group">
<label for="username">Username</label>
<input id="username" class="form-control" type="text" name="username" placeholder="Username*" required>
</div>
</div>
<div class="col-xs-4 col-xs-offset-0">
<div class="form-group">
<label for="password">Password</label>
<input id="password" class="form-control" type="password" name="password" placeholder="Password*" required>
</div>
</div>
</div>
<div class="row">
<div class="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-xs-4 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-xs-4 col-xs-offset-0">
<div class="form-group">
<label for="number">Enter: I Love Camping</label>
<input id="number" class="form-control" type="text" name="answer" placeholder="Answer*" required>
</div>
</div>
</div>
<div class="row">
<div class="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-xs-12">
<p class="text-center"><strong>*</strong> indicates a required field.</p>
</div>
</div>
</div>
<% include ./partials/footer %>
If I use enctype="multipart/form-data" I get an error for some reason but if I leave it off it completes but the image still doesnt upload. Just reverts to the no-image.png
If You want to post file You've to use entype="multipart/form-data":
<form action="/register" method="post" enctype="multipart/form-data">
If You've other problems so fix that problem.
from documentation :
.single(fieldname)
Accept a single file with the name fieldname. The single file will be stored in req.file.
So create upload method like this and call it in Your router:
var uploadAvatar = multer({ storage : storage}).single('avatar');
or rename Your input file name="image" :
<input id="avatar" class="form-control" type="file" name="image">

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.

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>

Resources