how to update data using put request in express js,mongodb - node.js

This is form and displays single data in this.
singlepassword.js
<html>
<%- include("./partials/head.ejs") %>
<body>
<%- include("./partials/nav.ejs") %>
<div class="container" style="height:379px;">
<div class="row m-3">
<form class="col-sm-10 offset-sm-1" method="POST" action="/details">
<div class="row">
<h3 class="col-sm-9 text-info mt-2 mb-2">View Single data</h3>
<span class="col-sm-3 btn-group">
<a role="button" class="btn btn-success" data-doc="<%= selection._id%>">Update</a>
<a role="button" class="btn btn-danger delete" data-doc="<%= selection._id%>">Delete</a>
<a role="button" class="btn btn-secondary" href="/details">Cancel</a>
</span>
</div>
<input type="hidden" value="<%= selection._id%>"/>
<div class="form-group"><label class="form-label text-light" for="website">Website</label><input class="form-control text-dark" id="website" type="text" name="website" value="<%= selection.website %>" required></div>
<div class="form-group"><label class="form-label text-light" for="username">User Name</label><input class="form-control text-dark" id="username" type="text" name="username" value="<%= selection.username %>" required></div>
<div class="form-group"><label class="form-label text-light" for="pass">Password</label><input class="form-control text-dark" id="pass" type="password" name="password" value="<%= selection.password %>" required></div>
</form>
</div>
</div>
<%- include("./partials/footer.ejs") %>
<script>
const trashcan = document.querySelector('a.delete');
trashcan.addEventListener('click', (e) => {
const endpoint = `/details/${trashcan.dataset.doc}`;
fetch(endpoint, {
method: 'DELETE',
})
.then(response => response.json())
.then(data => window.location.href = data.redirect)
.catch(err => console.log(err));
});
</script>
</body>
</html>
this is the routing file and put request includes in this file.
passwordRoutes.js
const express = require('express');
const Password = require('../models/passwordList');
const router = express.Router();
//update data
router.put((req,res)=>{
const id = req.params.id;
Password.findByIdAndUpdate(id)
.then((result) =>{
console.log(result);
})
.catch((err) =>{
console.log(err);
});
})
module.exports = router ;
this file includes mongoose schemas.
passwordList.js
const mongoose = require ('mongoose');
const Schema = mongoose.Schema;
const passwordSchema = new Schema({
website:{
type: String,
required : true
},
username:{
type: String,
required : true
},
password:{
type:String,
required:true
}
}, {timestamps: true});
const PasswordList = mongoose.model('PasswordList', passwordSchema);
module.exports = PasswordList;
How do update data when clicking the update button using put request?
After update data , should redirect details.js page

Related

How to check if a username is taken in Mongo Schema with an AJAX API call

I am trying to create a registration form where a potential user is typing in their desired username it checks against the existing Mongo DB User Schema to see if that exact name exists.
The form I have is here:
<form class="needs-validation" action="/register" method="POST" novalidate>
<div class="text-center mb-3">
<p class="lead">Welcome to the team! We just need a few things to get started.</p>
<div class="row">
<div class="col-md-6 mb-4">
<div class="form-outline">
<input
type="text"
id="first_name"
name="first_name"
class="form-control"
required
/>
<label class="form-label" for="first_name"
>First name</label
>
<div class="valid-feedback">Looks good!</div>
<div class="invalid-feedback">Thats not right</div>
</div>
</div>
<div class="col-md-6 mb-4">
<div class="form-outline">
<input
type="text"
id="last-name"
name="last-name"
class="form-control"
required
/>
<label class="form-label" for="last-name"
>Last name</label
>
<div class="valid-feedback">Looks good!</div>
<div class="invalid-feedback">Thats not right</div>
</div>
</div>
</div>
<!-- Email input -->
<div class="form-outline mb-4">
<input
type="email"
id="register_email"
name="register_email"
class="form-control"
required
/>
<label class="form-label" for="register_email">Email</label>
<div class="valid-feedback">Looks good!</div>
<div class="invalid-feedback">Thats not right</div>
</div>
<div class="text-center mb-3">
<div class="form-outline mb-4">
<input type="text" id="register_username" name="register_username" class="form-control" placeholder="enter your username" required />
<label class="form-label" for="register_username">Username</label>
<div id="username-check"></div>
</div>
<!-- Password input -->
<div class="form-outline mb-4">
<input type="password" id="register_password" name="register_password" class="form-control" required/>
<label class="form-label" for="register_password">Password</label>
</div>
</div>
<!-- Submit button -->
<div class="text-center">
<button type="submit" id="register" class="btn btn-lg btn-rounded bg-insider link-dark mb-3 fw-bold" disabled>
Lets Go! <i class="fa-solid fa-gauge-max"></i>
</button>
</div>
</form>
I have this script code working on the page to take the user input and check to a get route that should be checking my MongoDB:
$('#register_username').on('keyup', function () {
$.get('/usercheck?username=' + $(this).val().toLowerCase(), function (response) {
$('#username-check').text(response.message);
console.log('')
var btn = document.getElementById('register');
btn.disabled = true;
if ($('#username-check').html() === "user exists") {
$('#username-check').text('username not available').css('color', 'red');
}
else {
console.log($('#register_username').val())
$('#username-check').text('username is available').css('color', 'green');
btn.disabled = false;
}
})
});
This is the route it calls to check the database:
var express = require("express"),
router = express.Router(),
passport = require("passport"),
User = require("../models/user");
router.get('/usercheck', function(req, res) {
console.log(req.query);
User.findOne({username: req.query.register_username}, function(err, username){
if(err) {
console.log(err);
}
var message;
if(username) {
console.log(username);
message = "user exists";
console.log(message);
} else {
message= "user doesn't exist";
console.log(message);
}
res.json({message: message});
});
});
module.exports = router;
In case this helps, this is the user Schema in the database:
var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var UserSchema = new mongoose.Schema({
username: String,
password: String,
email: String,
isAdmin: { type: Boolean, default: false }
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User",UserSchema);
I am not sure what I am missing but anything would be extremely helpful. Thanks in advance!
Just so this question can be closed successfully:
Changing /usercheck?username= to /usercheck?register_username= did the trick, because this query param was used in the form:
$('#register_username').on('keyup', function () {
$.get('/usercheck?register_username=' + $(this).val().toLowerCase(), function (response) {
$('#username-check').text(response.message);
console.log('')
var btn = document.getElementById('register');
btn.disabled = true;
if ($('#username-check').html() === "user exists") {
$('#username-check').text('username not available').css('color', 'red');
}
else {
console.log($('#register_username').val())
$('#username-check').text('username is available').css('color', 'green');
btn.disabled = false;
}
})
});

req.body() is getting empty while inserting data in MERN

I have MERN project where i have to simply put my form data in my database. All looking good but data is not inserting. while there is no error also.
I have done console.log(req.body). after i getting empty {}.
As i have tried so many previous question in stackoverflow but noe of them helps me
this is my screenshot of console of my browser
Showing staus 201 but data is not going in my database
How to debug this error. I have tried all solution. Atleast tell me the possible reasons of this error. it will help me a lot. i am trying from full 1 day
userSchema
const userSchema = new mongoose.Schema({
identity: {
type: String,
},
names: {
type: String,
},
phone: {
type: String,
},
email: {
type: String,
},
city: {
type: String,
},
address: {
type: String,
},
subject: {
type: String,
},
classes: {
type: String,
},
message: {
type: String,
},
})
const USER = mongoose.model("USER", userSchema)
module.exports = USER
register.js(frontend)
const Register = () => {
const [newUser, setNewUser] = useState({
identity: "",
names: "",
phone: "",
email: "",
city: "",
address: "",
subject: "",
classes: "",
message: "",
});
const handleSubmit = (e) => {
e.preventDefault();
const formData = new FormData();
formData.append("identity", newUser.identity);
formData.append("names", newUser.names);
formData.append("phone", newUser.phone);
formData.append("email", newUser.email);
formData.append("city", newUser.city);
formData.append("address", newUser.address);
formData.append("subject", newUser.subject);
formData.append("classes", newUser.classes);
formData.append("message", newUser.message);
axios({
method: "post",
url: "/register",
data: formData,
headers: { "Content-Type": "application/json" },
})
.then((response) => {
console.log(response);
})
.then((data) => {
console.log(data);
})
.catch((error) => {
if (error.response) {
console.log(error.response.data);
}
});
};
const handleChange = (e) => {
setNewUser({ ...newUser, [e.target.name]: e.target.value });
};
return (
<>
<div class="container register mt-5">
<h1 class="well text-register shadow p-4 rounded-3">
Join as{" "}
<label class="student">
[{" "}
<img src="https://img.icons8.com/external-vitaliy-gorbachev-lineal-color-vitaly-gorbachev/60/000000/external-man-avatars-vitaliy-gorbachev-lineal-color-vitaly-gorbachev-12.png" />{" "}
Parent/Student{" "}
<img src="https://img.icons8.com/external-justicon-lineal-color-justicon/64/000000/external-student-back-to-school-justicon-lineal-color-justicon.png" />{" "}
]
</label>
<h1 class="well text-register down">
<i class="fas fa-arrow-right"></i> Hey! If you are looking for right
tutor near by your location. Don't worry you are at right place.{" "}
<i class="fas fa-arrow-left"></i>
</h1>
</h1>
<div class="col-lg-12 well rounded-3">
<div class="row mt-5 ">
<form onSubmit={handleSubmit} method = "post" class="shadow p-5">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-12 form-group">
<label>
{" "}
<i class="far fa-dot-circle"></i> Your Identity
</label>
<input
type="text"
placeholder="Write Student or Parent"
class="form-control"
name="identity"
id="identity"
value={newUser.identity}
onChange={handleChange}
/>
</div>
</div>
<div class="form-group">
<label>
{" "}
<i class="far fa-dot-circle"></i> Name
</label>
<input
type="text"
placeholder="Enter Your Full Name Here.."
class="form-control"
name="names"
id="names"
value={newUser.names}
onChange={handleChange}
/>
</div>
<div class="form-group">
<label>
{" "}
<i class="far fa-dot-circle"></i> Phone Number
</label>
<input
type="text"
placeholder="Enter Phone Number Here.."
class="form-control"
name="phone"
id="phone"
value={newUser.phone}
onChange={handleChange}
/>
</div>
<div class="form-group">
<label>
{" "}
<i class="far fa-dot-circle"></i> Email Address
</label>
<input
type="text"
placeholder="Enter Email Address Here.."
class="form-control"
name="email"
id="email"
value={newUser.email}
onChange={handleChange}
/>
</div>
<div class="row">
<div class="col-sm-6 form-group">
<label>
{" "}
<i class="far fa-dot-circle"></i> City
</label>
<input
type="text"
placeholder="Enter City Name Here.."
class="form-control"
name="city"
id="city"
value={newUser.city}
onChange={handleChange}
/>
</div>
<div class="col-sm-6 form-group">
<label>
{" "}
<i class="far fa-dot-circle"></i> Address
</label>
<textarea
placeholder="Enter Address Here.."
rows="3"
class="form-control"
name="address"
id="address"
value={newUser.address}
onChange={handleChange}
></textarea>
</div>
</div>
<div class="row">
<div class="col-sm-6 form-group">
<label>
{" "}
<i class="far fa-dot-circle"></i> Subject
</label>
<input
type="text"
placeholder="Enter Subject Here.."
class="form-control"
name="subject"
id="subject"
value={newUser.subject}
onChange={handleChange}
/>
</div>
<div class="col-sm-6 form-group">
<label>
{" "}
<i class="far fa-dot-circle"></i>Student Class
</label>
<input
type="text"
placeholder="Enter Student Class"
class="form-control"
name="classes"
id="classes"
value={newUser.classes}
onChange={handleChange}
/>
</div>
</div>
<div class="form-group">
<label>
{" "}
<i class="far fa-dot-circle"></i> Message
</label>
<textarea
placeholder="Enter Any message you have for us..."
rows="3"
class="form-control"
name="message"
id="message"
value={newUser.message}
onChange={handleChange}
></textarea>
</div>
<button value="register" type="submit" class="btn btn-lg btn-info">
Submit
</button>
</div>
</form>
</div>
</div>
</div>
</>
);
};
auth.js
router.get("/", (req, res) => {
res.send("hello, i am communicating with router");
})
router.post("/register", async (req, res) => {
const { identity, names, phone, email, city, address, subject, classes, message } = req.body
console.log(req.body)
try {
const user = new User({identity ,names, phone,email,city,address, subject, classes, message })
await user.save()
res.status(201).json({ message: "user registered successfulluy" })
} catch (err) {
console.log(err)
}
})
module.exports = router
app.js
const port = 5000
env.config({path: "../server/config.env"})
require("../server/db/conn")
app.use(cors());
app.use(express.json())
app.use(require("../server/router/Auth"))
app.listen(port, (err) => {
if (err) {
return console.error(err);
}
return console.log(`server is listening on ${port}`);
});
Please help. i have tried so many times!!
Thankyou!!!
Modify Your HandleSubmit function, do not use formData to submit your data as application/json
Instead, just use your current React State
const handleSubmit = (e) => {
e.preventDefault();
axios({
method: "post",
url: "/register",
data: JSON.stringify(newUser),
headers: { "Content-Type": "application/json" },
})
.then((response) => {
console.log(response);
})
.then((data) => {
console.log(data);
})
.catch((error) => {
if (error.response) {
console.log(error.response.data);
}
});
};

Mongoose doesnt save multiline string

When i try to put a multiline string into a mongoose database it doesnt want to work. It just saves one line of the string.
Logging content to console:
Website result:
EJS Code
<% posts.forEach(function(post){ %>
<div class="card mb-2" style="width: 100%;">
<div class="card-body">
<% if(user.admin == true || user.id == post.authorid){ %>
<form action="/deletepost/<%= post.id %>" method="post">
<button type="submit" class="btn btn-sm btn-danger btn-block">Delete</button>
</form>
<br>
<% } %>
<h5 class="card-title"><%= post.authorname %></h5>
<h6 class="card-subtitle mb-2 text-muted"><%= post.date %></h6>
<hr>
<p class="card-text"><%= post.content %></p>
</div>
</div>
<% }); %>
Mongoose model:
const PostSchema = new mongoose.Schema({
content: {
type: String
}
})
How i save to database:
var newPost = {content, authorid, authorname};
Post.create(newPost, function(err, newlyCreated){
if(err){
console.log(err);
} else {
res.redirect("/app")
}
});
I use express & ejs if that matters.

Working form with file upload image in expressjs

What is the simple proper way to upload an image with the form?
I want to upload an image with the form. I have tried working it out but I got "unexpected field". I have installed multer and followed a simple tutorial but not working as expected
This is my route
var express = require('express');
const multer = require('multer');
var router = express.Router();
const multerConfig = {
storage: multer.diskStorage({
//setup where the user's file will go
destination: function(req, file, next){
next(null, './public/images');
},
//then give the file a unique name here
filename: function(reg, file, next){
console.log(file);
const ext = file.mimetype.split('/')[1];
next(null, file.fieldname + '-' + Date.now() + '.'+ext)
}
}),
//a means of ensuring only images are uploaded.
fileFilter: function(req, file, next){
if(!file){
next();
}
const image = file.mimetype.startsWith('image/');
if(image){
console.log('photo uploaded');
next(null, true);
}else{
console.log('file not supported');
return next();
}
}
}
var bookControllers = require("../controllers/bookControllers")
//const csrf = require("../app");
/* GET home page.
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
*/
router.get('/', bookControllers.index);
router.post('/addbooks', multer(multerConfig).single('photo'), bookControllers.addbooks);
router.get('/addbooks/:id/:book_url', bookControllers.vieweachbook);
//router.get('/addbooks/:id/edit', bookControllers.edit);
router.get("/:id/edit", bookControllers.edit);
router.get('/:id/delete', bookControllers.delete);
router.put("/:id/update", bookControllers.update);
module.exports = router;
This is addbooks in bookControllers.js
exports.addbooks = function (req, res)
{
const schema = Joi.object().keys({
book_name: Joi.string().trim().min(6).max(25).required(),
summaries: Joi.string().trim().required(),
isbn: Joi.number().required(),
categories: Joi.string().trim().required(),
});
Joi.validate(req.body, schema, (err, result) => {
if(err){
console.log(err)
return res.redirect("/");
}
var url = slug(req.body.categories, {lower: true});
var book_url = slug(req.body.book_name, {lower: true});
//I have to get the auth user and add to the field later
var author = "1";
//Perform knex insert into db
knex('book').insert({
book_name: req.body.book_name,
author: author,
summary: req.body.summaries,
isbn: req.body.isbn,
category: req.body.categories,
image: req.body.image,
url: url,
book_url: book_url
}).then(function(result){
console.log(err)
return res.redirect('/');
});
});
}
and this is the form
<div class="col-lg-4">
<div class="card">
<div class="card-header bg-primary"> Add Books </div>
<form id="c_form-h" class="" method="post" action="/addbooks" enctype="multipart/form-data" style="padding: 5px;">
<div class="form-group row">
<label for="addbookname" class="col-6 col-form-label">Book Name</label>
<div class="col-12">
<input type="text" class="form-control" name="book_name" placeholder="Add Book Name" required>
</div>
</div>
<div class="form-group row">
<label for="addsummary" class="col-6 col-form-label">Summary</label>
<div class="col-12">
<textarea class="form-control" name="summaries" placeholder="Write Some Description" rows="3" required>
</textarea>
</div>
</div>
<div class="form-group row">
<label for="addcategory" class="col-9 col-form-label">Select Category</label>
<div class="col-12">
<input type="number" class="form-control" name="isbn" placeholder="ISBN" required>
</div>
</div>
<div class="form-group row">
<label for="addimage" class="col-9 col-form-label">Add Image</label>
<div class="col-12">
<input type="file" class="form-control-file" name="image" required>
</div>
</div>
<div class="form-group row">
<label for="addcategory" class="col-9 col-form-label">Select Category</label>
<div class="col-12">
<select class="form-control" name="categories" required>
<option></option>
<option>Fruits</option>
<option>Intercontinental Foods</option>
<option>3</option>
<option>4</option>
</select>
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
Also, can some also give me a hint on image update? I mean How to change the image
Thanks
In your HTML you have a file name as image
<input type="file" class="form-control-file" name="image" required>
So, You need to mention the same file name on multer as image instead photo
//Replaced photo with image
router.post('/addbooks', multer(multerConfig).single('image'), bookControllers.addbooks);
Reference : Multer - API Documentation
Update Path on Database :
You will get the file information in req.file on your controller, Like
{ fieldname, originalname, encoding, mimetype, destination, filename, path, size }
Depends on your need you can save file information on your database
knex('book').insert({
...
image: req.file.path,
....
}).then(function(result){

Insert in bulk using Sequelize with Node and Express

Looking for a way to insert activities to the database in bulk using Sequelize Model.bulkCreate.
Not sure how to bring the activities from the view to the route function in order to insert them using bulkCreate. Right now I only insert one activity.
View:
<form action="/create" method="POST">
<div class="form-group">
<label>Plan Name</label>
<input type="text" name="plan_name" placeholder="Plan Name">
</div>
<div class="form-group">
<label>Description</label>
<input type="text" name="description" placeholder="Description">
</div>
<div class="form-group">
<label>Activity</label>
<input type="text" name="activity_name" placeholder="Activity">
<label>Comment</label>
<input type="text" name="comment" placeholder="Comment">
<input type="button" id="add" class="btn btn-success" value="Add">
</div>
<div class="form-group" id="new">
</div>
<input type="hidden" name="_csrf" value="{{csrfToken}}">
<input type="submit" class="btn btn-success" value="Submit">
</form>
<script type="text/javascript">
$('#add').click(function() {
let activity = $('<div class="form-group"><label>Activity</label><input type="text" name="activity_name" placeholder="Activity"><label>Comment</label><input type="text" name="comment" placeholder="Comment"></div>');
$('#new').append(activity);
});
</script>
Route:
app.post('/create', (req, res) => {
const user_id = req.user.id;
const data = {
plan_name: req.body.plan_name,
description: req.body.description,
userId: user_id
};
PlanModel.Plan.create(data).then(plan => {
const activity = {
activity_name: req.body.activity_name,
comment: req.body.comment,
plans_id: plan.id
};
ActivityModel.Activity.create(activity);
res.redirect('/');
});
});
1) Make fields to have names like an array
<div class="activities">
<div class="form-group">
<label>Activity</label>
<input type="text" name="activities[0][name]" placeholder="Activity">
<label>Comment</label>
<input type="text" name="activities[0][comment]" placeholder="Comment">
</div>
<div class="form-group">
<label>Activity</label>
<input type="text" name="activities[1][name]" placeholder="Activity">
<label>Comment</label>
<input type="text" name="activities[1][comment]" placeholder="Comment">
</div>
</div>
<div class="form-group>
<input type="button" id="add" class="btn btn-success" value="Add">
</div>
2) At server-side just take that req.body.activities and generate array of objects and call bulkCreate
app.post('/create', async (req, res) => {
try {
const data = {
plan_name: req.body.plan_name,
description: req.body.description,
userId: req.user.id
};
const plan = await PlanModel.Plan.create(data);
if (req.body.activities && Array.isArray(req.body.activities)) {
const activities = req.body.activities.map(
activity => {
return {
activity_name: activity.name,
comment: activity.comment,
plans_id: plan.id
}
});
await ActivityModel.Activity.bulkCreate(activities);
}
res.redirect('/');
}
catch(error) {
res.status(500).send(error);
}
});
3) Since body parser for urlencoded mode has extended option that parses deeply all of the fields. You've to enable it.
MAKE SURE that bodyParser middleware attached with extended: true :
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: true}));

Resources